summaryrefslogtreecommitdiffstats
path: root/sal/qa/rtl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sal/qa/rtl
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sal/qa/rtl')
-rw-r--r--sal/qa/rtl/alloc/rtl_alloc.cxx211
-rw-r--r--sal/qa/rtl/bootstrap/expand.cxx58
-rw-r--r--sal/qa/rtl/cipher/rtl_cipher.cxx600
-rw-r--r--sal/qa/rtl/crc32/rtl_crc32.cxx154
-rw-r--r--sal/qa/rtl/digest/rtl_digest.cxx515
-rw-r--r--sal/qa/rtl/doublelock/rtl_doublelocking.cxx182
-rw-r--r--sal/qa/rtl/locale/rtl_locale.cxx280
-rw-r--r--sal/qa/rtl/math/test-rtl-math.cxx677
-rw-r--r--sal/qa/rtl/ostring/rtl_OString2.cxx508
-rw-r--r--sal/qa/rtl/ostring/rtl_str.cxx724
-rw-r--r--sal/qa/rtl/ostring/rtl_str.xsce43
-rw-r--r--sal/qa/rtl/ostring/rtl_string.cxx169
-rw-r--r--sal/qa/rtl/ostring/rtl_string.xsce18
-rw-r--r--sal/qa/rtl/oustring/joblist.txt27
-rw-r--r--sal/qa/rtl/oustring/rtl_OUString2.cxx1068
-rw-r--r--sal/qa/rtl/oustring/rtl_ustr.cxx1080
-rw-r--r--sal/qa/rtl/oustring/rtl_ustr.xsce50
-rw-r--r--sal/qa/rtl/oustringbuffer/test_oustringbuffer_appendchar.cxx43
-rw-r--r--sal/qa/rtl/oustringbuffer/test_oustringbuffer_appenduninitialized.cxx66
-rw-r--r--sal/qa/rtl/oustringbuffer/test_oustringbuffer_assign.cxx92
-rw-r--r--sal/qa/rtl/oustringbuffer/test_oustringbuffer_tostring.cxx61
-rw-r--r--sal/qa/rtl/oustringbuffer/test_oustringbuffer_utf32.cxx121
-rw-r--r--sal/qa/rtl/process/child_process.cxx60
-rw-r--r--sal/qa/rtl/process/child_process_id.cxx54
-rw-r--r--sal/qa/rtl/process/rtl_Process.cxx258
-rw-r--r--sal/qa/rtl/process/rtl_Process_Const.h40
-rw-r--r--sal/qa/rtl/random/random.txt22
-rw-r--r--sal/qa/rtl/random/rtl_random.cxx363
-rw-r--r--sal/qa/rtl/ref/rtl_ref.cxx115
-rw-r--r--sal/qa/rtl/strings/compile-oustring.cxx45
-rw-r--r--sal/qa/rtl/strings/nonconstarray.cxx94
-rw-r--r--sal/qa/rtl/strings/test_ostring.cxx123
-rw-r--r--sal/qa/rtl/strings/test_ostring_concat.cxx206
-rw-r--r--sal/qa/rtl/strings/test_ostring_stringliterals.cxx282
-rw-r--r--sal/qa/rtl/strings/test_ostringbuffer.cxx56
-rw-r--r--sal/qa/rtl/strings/test_oustring_compare.cxx97
-rw-r--r--sal/qa/rtl/strings/test_oustring_concat.cxx213
-rw-r--r--sal/qa/rtl/strings/test_oustring_convert.cxx177
-rw-r--r--sal/qa/rtl/strings/test_oustring_endswith.cxx113
-rw-r--r--sal/qa/rtl/strings/test_oustring_startswith.cxx38
-rw-r--r--sal/qa/rtl/strings/test_oustring_stringliterals.cxx432
-rw-r--r--sal/qa/rtl/strings/test_strings_defaultstringview.cxx118
-rw-r--r--sal/qa/rtl/strings/test_strings_replace.cxx339
-rw-r--r--sal/qa/rtl/strings/test_strings_toint.cxx72
-rw-r--r--sal/qa/rtl/strings/test_strings_valuex.cxx115
-rw-r--r--sal/qa/rtl/textenc/rtl_tencinfo.cxx1674
-rw-r--r--sal/qa/rtl/textenc/rtl_textcvt.cxx3313
-rw-r--r--sal/qa/rtl/uri/rtl_Uri.cxx79
-rw-r--r--sal/qa/rtl/uri/rtl_testuri.cxx514
-rw-r--r--sal/qa/rtl/uuid/rtl_Uuid.cxx159
50 files changed, 15918 insertions, 0 deletions
diff --git a/sal/qa/rtl/alloc/rtl_alloc.cxx b/sal/qa/rtl/alloc/rtl_alloc.cxx
new file mode 100644
index 000000000..419a3f3b0
--- /dev/null
+++ b/sal/qa/rtl/alloc/rtl_alloc.cxx
@@ -0,0 +1,211 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include "../../../rtl/strimp.hxx"
+
+#include <memory.h>
+
+namespace rtl_alloc
+{
+
+ // small memory check routine, which return false, if there is a problem
+
+ static bool checkMemory(const char* _pMemory, sal_uInt32 _nSize, char _n)
+ {
+ bool bOk = true;
+
+ for (sal_uInt32 i=0;i<_nSize;i++)
+ {
+ if (_pMemory[i] != _n)
+ {
+ bOk = false;
+ }
+ }
+ return bOk;
+ }
+
+class Memory : public CppUnit::TestFixture
+{
+ // for normal alloc functions
+ char *m_pMemory;
+ static const sal_uInt32 m_nSizeOfMemory = 1024;
+
+public:
+ Memory()
+ : m_pMemory(nullptr)
+ {
+ }
+
+ // initialise your test code values here.
+ void setUp() override
+ {
+ m_pMemory = static_cast<char*>(rtl_allocateMemory( m_nSizeOfMemory ));
+ }
+
+ void tearDown() override
+ {
+ rtl_freeMemory(m_pMemory);
+ m_pMemory = nullptr;
+ }
+
+ void rtl_allocateMemory_001()
+ {
+ CPPUNIT_ASSERT_MESSAGE( "Can get zero memory.", m_pMemory != nullptr);
+ memset(m_pMemory, 1, m_nSizeOfMemory);
+ CPPUNIT_ASSERT_MESSAGE( "memory contains wrong value.", checkMemory(m_pMemory, m_nSizeOfMemory, 1));
+ }
+
+ void rtl_reallocateMemory_001()
+ {
+ sal_uInt32 nSize = 2 * 1024;
+ m_pMemory = static_cast<char*>(rtl_reallocateMemory(m_pMemory, nSize));
+
+ CPPUNIT_ASSERT_MESSAGE( "Can reallocate memory.", m_pMemory != nullptr);
+ memset(m_pMemory, 2, nSize);
+ CPPUNIT_ASSERT_MESSAGE( "memory contains wrong value.", checkMemory(m_pMemory, nSize, 2));
+ }
+
+ CPPUNIT_TEST_SUITE(Memory);
+ CPPUNIT_TEST(rtl_allocateMemory_001);
+ CPPUNIT_TEST(rtl_reallocateMemory_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class test
+
+class TestZeroMemory : public CppUnit::TestFixture
+{
+ // for zero functions
+ char *m_pZeroMemory;
+ static const sal_uInt32 m_nSizeOfZeroMemory = 50 * 1024 * 1024;
+
+public:
+ TestZeroMemory()
+ : m_pZeroMemory(nullptr)
+ {
+ }
+
+ // initialise your test code values here.
+ void setUp() override
+ {
+ m_pZeroMemory = static_cast<char*>(rtl_allocateZeroMemory( m_nSizeOfZeroMemory ));
+ }
+
+ void tearDown() override
+ {
+ rtl_freeZeroMemory(m_pZeroMemory, m_nSizeOfZeroMemory);
+ // LLA: no check possible, may GPF if there is something wrong.
+ // CPPUNIT_ASSERT_MESSAGE( "Can get zero memory.", pZeroMemory != NULL);
+ }
+
+ // insert your test code here.
+
+ void rtl_allocateZeroMemory_001()
+ {
+ CPPUNIT_ASSERT_MESSAGE( "Can get zero memory.", m_pZeroMemory != nullptr);
+ CPPUNIT_ASSERT_MESSAGE( "memory contains wrong value.", checkMemory(m_pZeroMemory, m_nSizeOfZeroMemory, 0));
+
+ memset(m_pZeroMemory, 3, m_nSizeOfZeroMemory);
+ CPPUNIT_ASSERT_MESSAGE( "memory contains wrong value.", checkMemory(m_pZeroMemory, m_nSizeOfZeroMemory, 3));
+ }
+
+ CPPUNIT_TEST_SUITE(TestZeroMemory);
+ CPPUNIT_TEST(rtl_allocateZeroMemory_001);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+class TestPreinit : public CppUnit::TestFixture
+{
+public:
+ TestPreinit()
+ {
+ }
+
+ // initialise your test code values here.
+ void setUp() override
+ {
+ }
+
+ void tearDown() override
+ {
+ }
+
+ // insert your test code here.
+
+ void test()
+ {
+ const char sample[] = "Hello World";
+ std::vector<OUString> aStrings;
+
+ rtl_alloc_preInit(true);
+
+ OUString aFoo("foo");
+
+ // fill some cache bits
+ for (int iter = 0; iter < 4; iter++)
+ {
+ for (int i = 1; i < 4096; i += 8)
+ {
+ OUStringBuffer aBuf(i);
+ aBuf.appendAscii(sample, (i/8) % (SAL_N_ELEMENTS(sample)-1));
+ OUString aStr = aBuf.makeStringAndClear();
+ aStrings.push_back(aStr);
+ }
+ // free some pieces to make holes
+ for (size_t i = iter; i < aStrings.size(); i += 17)
+ aStrings[i] = aFoo;
+ }
+
+ for (size_t i = 0; i < aStrings.size(); ++i)
+ {
+ CPPUNIT_ASSERT_MESSAGE( "not static before.", !(aStrings[i].pData->refCount & SAL_STRING_STATIC_FLAG) );
+ }
+
+ // should static-ize all the strings.
+ rtl_alloc_preInit(false);
+
+ for (size_t i = 0; i < aStrings.size(); ++i)
+ CPPUNIT_ASSERT_MESSAGE( "static after.", (aStrings[i].pData->refCount & SAL_STRING_STATIC_FLAG) );
+ }
+
+ void test2()
+ {
+ // should never happen but lets try it again.
+ test();
+ }
+
+ CPPUNIT_TEST_SUITE(TestPreinit);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST(test2);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_alloc::Memory);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_alloc::TestZeroMemory);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_alloc::TestPreinit);
+} // namespace rtl_alloc
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/bootstrap/expand.cxx b/sal/qa/rtl/bootstrap/expand.cxx
new file mode 100644
index 000000000..e9799c15f
--- /dev/null
+++ b/sal/qa/rtl/bootstrap/expand.cxx
@@ -0,0 +1,58 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+
+namespace {
+
+class Test: public CppUnit::TestFixture {
+public:
+ virtual void setUp() override;
+
+private:
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testDollar);
+ CPPUNIT_TEST(testIndirectDollar);
+ CPPUNIT_TEST_SUITE_END();
+
+ void testDollar();
+
+ void testIndirectDollar();
+};
+
+void Test::setUp() {
+ rtl::Bootstrap::set("TEST", "<expanded TEST>");
+ rtl::Bootstrap::set("WITH_DOLLAR", "foo\\$TEST");
+ rtl::Bootstrap::set("INDIRECT", "$WITH_DOLLAR");
+}
+
+void Test::testDollar() {
+ OUString s("$WITH_DOLLAR");
+ rtl::Bootstrap::expandMacros(s);
+ CPPUNIT_ASSERT_EQUAL(OUString("foo$TEST"), s);
+}
+
+void Test::testIndirectDollar() {
+ OUString s("$INDIRECT");
+ rtl::Bootstrap::expandMacros(s);
+ CPPUNIT_ASSERT_EQUAL(OUString("foo$TEST"), s);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/cipher/rtl_cipher.cxx b/sal/qa/rtl/cipher/rtl_cipher.cxx
new file mode 100644
index 000000000..1f6852184
--- /dev/null
+++ b/sal/qa/rtl/cipher/rtl_cipher.cxx
@@ -0,0 +1,600 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cstring>
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/cipher.h>
+
+namespace rtl_cipher
+{
+
+class create : public CppUnit::TestFixture
+{
+public:
+
+ void create_001()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ void create_002()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmInvalid, rtl_Cipher_ModeECB);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("create provide wrong object.", static_cast<rtlCipher>(nullptr), aCipher);
+ }
+ void create_003()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeCBC);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ void create_004()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmInvalid, rtl_Cipher_ModeCBC);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("create provide wrong object.", static_cast<rtlCipher>(nullptr), aCipher);
+ }
+ void create_005()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream);
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroy(aCipher);
+ }
+ void create_006()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmInvalid, rtl_Cipher_ModeStream);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("create provide wrong object.", static_cast<rtlCipher>(nullptr), aCipher);
+ }
+ void create_007()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeInvalid);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("create provide wrong object.", static_cast<rtlCipher>(nullptr), aCipher);
+ }
+ void create_008()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmInvalid, rtl_Cipher_ModeInvalid);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("create provide wrong object.", static_cast<rtlCipher>(nullptr), aCipher);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(create);
+ CPPUNIT_TEST(create_001);
+ CPPUNIT_TEST(create_002);
+ CPPUNIT_TEST(create_003);
+ CPPUNIT_TEST(create_004);
+ CPPUNIT_TEST(create_005);
+ CPPUNIT_TEST(create_006);
+ CPPUNIT_TEST(create_007);
+ CPPUNIT_TEST(create_008);
+ CPPUNIT_TEST_SUITE_END();
+}; // class create
+
+class createBF : public CppUnit::TestFixture
+{
+public:
+
+ void createBF_001()
+ {
+ rtlCipher aCipher = rtl_cipher_createBF(rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ void createBF_002()
+ {
+ rtlCipher aCipher = rtl_cipher_createBF(rtl_Cipher_ModeCBC);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ void createBF_003()
+ {
+ rtlCipher aCipher = rtl_cipher_createBF(rtl_Cipher_ModeStream);
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroy(aCipher);
+ }
+ void createBF_004()
+ {
+ rtlCipher aCipher = rtl_cipher_createBF(rtl_Cipher_ModeInvalid);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("create provide wrong object.", static_cast<rtlCipher>(nullptr), aCipher);
+ // rtl_cipher_destroy(aCipher);
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(createBF);
+ CPPUNIT_TEST(createBF_001);
+ CPPUNIT_TEST(createBF_002);
+ CPPUNIT_TEST(createBF_003);
+ CPPUNIT_TEST(createBF_004);
+ CPPUNIT_TEST_SUITE_END();
+}; // class createBF
+
+class decode : public CppUnit::TestFixture
+{
+public:
+
+ void test_encode(sal_uInt8 _nKeyValue, sal_uInt8 _nArgValue, OString const& _sPlainTextStr)
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+ (void) _nKeyValue;
+ (void) _nArgValue;
+ (void) _sPlainTextStr;
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+
+ sal_uInt32 nKeyLen = 16;
+ sal_uInt8 *pKeyBuffer = new sal_uInt8[ nKeyLen ];
+ memset(pKeyBuffer, 0, nKeyLen);
+ pKeyBuffer[0] = _nKeyValue;
+
+ sal_uInt32 nArgLen = 16;
+ sal_uInt8 *pArgBuffer = new sal_uInt8[ nArgLen ];
+ memset(pArgBuffer, 0, nArgLen);
+ pArgBuffer[0] = _nArgValue;
+
+ rtlCipherError aError = rtl_cipher_init(aCipher, rtl_Cipher_DirectionEncode, pKeyBuffer, nKeyLen, pArgBuffer, nArgLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong init", rtl_Cipher_E_None, aError);
+
+ sal_uInt32 nPlainTextLen = 16;
+ sal_uInt8 *pPlainTextBuffer = new sal_uInt8[ nPlainTextLen ];
+ memset(pPlainTextBuffer, 0, nPlainTextLen);
+ strncpy(reinterpret_cast<char*>(pPlainTextBuffer), _sPlainTextStr.getStr(), 16);
+
+ sal_uInt32 nCipherLen = 16;
+ sal_uInt8 *pCipherBuffer = new sal_uInt8[ nCipherLen ];
+ memset(pCipherBuffer, 0, nCipherLen);
+
+ /* rtlCipherError */ aError = rtl_cipher_encode(aCipher, pPlainTextBuffer, nPlainTextLen, pCipherBuffer, nCipherLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong encode", rtl_Cipher_E_None, aError);
+
+ sal_uInt32 nPlainText2Len = 16;
+ sal_uInt8 *pPlainText2Buffer = new sal_uInt8[ nPlainText2Len ];
+ memset(pPlainText2Buffer, 0, nPlainText2Len);
+
+ /* rtlCipherError */ aError = rtl_cipher_decode(aCipher, pCipherBuffer, nCipherLen, pPlainText2Buffer, nPlainText2Len);
+ CPPUNIT_ASSERT_MESSAGE("decode should not work", aError != rtl_Cipher_E_None);
+
+ delete [] pPlainText2Buffer;
+
+ delete [] pCipherBuffer;
+ delete [] pPlainTextBuffer;
+
+ delete [] pArgBuffer;
+ delete [] pKeyBuffer;
+
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+
+ void test_encode_and_decode(sal_uInt8 _nKeyValue, sal_uInt8 _nArgValue, OString const& _sPlainTextStr)
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+ (void) _nKeyValue;
+ (void) _nArgValue;
+ (void) _sPlainTextStr;
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+
+ sal_uInt32 nKeyLen = 16;
+ sal_uInt8 *pKeyBuffer = new sal_uInt8[ nKeyLen ];
+ memset(pKeyBuffer, 0, nKeyLen);
+ pKeyBuffer[0] = _nKeyValue;
+
+ sal_uInt32 nArgLen = 16;
+ sal_uInt8 *pArgBuffer = new sal_uInt8[ nArgLen ];
+ memset(pArgBuffer, 0, nArgLen);
+ pArgBuffer[0] = _nArgValue;
+
+ rtlCipherError aError = rtl_cipher_init(aCipher, rtl_Cipher_DirectionBoth, pKeyBuffer, nKeyLen, pArgBuffer, nArgLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong init", rtl_Cipher_E_None, aError);
+
+ sal_uInt32 nPlainTextLen = 16;
+ sal_uInt8 *pPlainTextBuffer = new sal_uInt8[ nPlainTextLen ];
+ memset(pPlainTextBuffer, 0, nPlainTextLen);
+ strncpy(reinterpret_cast<char*>(pPlainTextBuffer), _sPlainTextStr.getStr(), 16);
+
+ sal_uInt32 nCipherLen = 16;
+ sal_uInt8 *pCipherBuffer = new sal_uInt8[ nCipherLen ];
+ memset(pCipherBuffer, 0, nCipherLen);
+
+ /* rtlCipherError */ aError = rtl_cipher_encode(aCipher, pPlainTextBuffer, nPlainTextLen, pCipherBuffer, nCipherLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong encode", rtl_Cipher_E_None, aError);
+
+ sal_uInt32 nPlainText2Len = 16;
+ sal_uInt8 *pPlainText2Buffer = new sal_uInt8[ nPlainText2Len ];
+ memset(pPlainText2Buffer, 0, nPlainText2Len);
+
+ /* rtlCipherError */ aError = rtl_cipher_decode(aCipher, pCipherBuffer, nCipherLen, pPlainText2Buffer, nPlainText2Len);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong decode", rtl_Cipher_E_None, aError);
+
+ sal_Int32 nCompare = memcmp(pPlainTextBuffer, pPlainText2Buffer, 16);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare between plain and decoded plain failed", static_cast<sal_Int32>(0), nCompare);
+
+ delete [] pPlainText2Buffer;
+
+ delete [] pCipherBuffer;
+ delete [] pPlainTextBuffer;
+
+ delete [] pArgBuffer;
+ delete [] pKeyBuffer;
+
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+
+ void decode_001()
+ {
+ test_encode_and_decode(0,0,"");
+ test_encode_and_decode(0,0,"hallo");
+ test_encode_and_decode(1,0,"B2Aahg5B");
+ test_encode_and_decode(1,2,"Longer text string");
+ }
+
+ void decode_002()
+ {
+ test_encode(0,0,"");
+ test_encode(0,0,"hallo");
+ test_encode(1,0,"B2Aahg5B");
+ test_encode(1,2,"Longer text string");
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(decode);
+ CPPUNIT_TEST(decode_001);
+ CPPUNIT_TEST(decode_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class decode
+
+class decodeBF : public CppUnit::TestFixture
+{
+public:
+
+ void decodeBF_001()
+ {
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(decodeBF);
+ CPPUNIT_TEST(decodeBF_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class decodeBF
+
+class destroy : public CppUnit::TestFixture
+{
+public:
+
+ void destroy_001()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeCBC);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(destroy);
+ CPPUNIT_TEST(destroy_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class destroy
+
+class destroyBF : public CppUnit::TestFixture
+{
+public:
+
+ void destroyBF_001()
+ {
+ rtlCipher aCipher = rtl_cipher_createBF(rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+ rtl_cipher_destroyBF(aCipher);
+ // more proforma
+ // should not GPF
+#endif
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(destroyBF);
+ CPPUNIT_TEST(destroyBF_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class destroyBF
+
+class encode : public CppUnit::TestFixture
+{
+public:
+
+ void test_encode(sal_uInt8 _nKeyValue, sal_uInt8 _nArgValue, sal_uInt8 _nDataValue)
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+ (void) _nKeyValue;
+ (void) _nArgValue;
+ (void) _nDataValue;
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+
+ sal_uInt32 nKeyLen = 16;
+ sal_uInt8 *pKeyBuffer = new sal_uInt8[ nKeyLen ];
+ memset(pKeyBuffer, 0, nKeyLen);
+ pKeyBuffer[0] = _nKeyValue;
+
+ sal_uInt32 nArgLen = 16;
+ sal_uInt8 *pArgBuffer = new sal_uInt8[ nArgLen ];
+ memset(pArgBuffer, 0, nArgLen);
+ pArgBuffer[0] = _nArgValue;
+
+ rtlCipherError aError = rtl_cipher_init(aCipher, rtl_Cipher_DirectionEncode, pKeyBuffer, nKeyLen, pArgBuffer, nArgLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong init", rtl_Cipher_E_None, aError);
+
+ sal_uInt32 nDataLen = 16;
+ sal_uInt8 *pDataBuffer = new sal_uInt8[ nDataLen ];
+ memset(pDataBuffer, 0, nDataLen);
+ pDataBuffer[0] = _nDataValue;
+
+ sal_uInt32 nLen = 16;
+ sal_uInt8 *pBuffer = new sal_uInt8[ nLen ];
+ memset(pBuffer, 0, nLen);
+
+ /* rtlCipherError */ aError = rtl_cipher_encode(aCipher, pDataBuffer, nDataLen, pBuffer, nLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong encode", rtl_Cipher_E_None, aError);
+
+ delete [] pBuffer;
+ delete [] pDataBuffer;
+
+ delete [] pArgBuffer;
+ delete [] pKeyBuffer;
+
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+
+ void encode_001()
+ {
+ test_encode(0,0,0);
+ test_encode(1,0,0);
+ test_encode(0,1,0);
+ test_encode(1,1,0);
+
+ test_encode(0,0,1);
+ test_encode(1,0,1);
+ test_encode(0,1,1);
+ test_encode(1,1,1);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(encode);
+ CPPUNIT_TEST(encode_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class encode
+
+class encodeBF : public CppUnit::TestFixture
+{
+public:
+
+ void encodeBF_001()
+ {
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(encodeBF);
+ CPPUNIT_TEST(encodeBF_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class encodeBF
+
+class init : public CppUnit::TestFixture
+{
+public:
+
+ void init_001()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+
+ sal_uInt32 nKeyLen = 16;
+ sal_uInt8 *pKeyBuffer = new sal_uInt8[ nKeyLen ];
+ memset(pKeyBuffer, 0, nKeyLen);
+
+ sal_uInt32 nArgLen = 16;
+ sal_uInt8 *pArgBuffer = new sal_uInt8[ nArgLen ];
+ memset(pArgBuffer, 0, nArgLen);
+
+ rtlCipherError aError = rtl_cipher_init(aCipher, rtl_Cipher_DirectionEncode, pKeyBuffer, nKeyLen, pArgBuffer, nArgLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong init", rtl_Cipher_E_None, aError);
+
+ delete [] pArgBuffer;
+ delete [] pKeyBuffer;
+
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+
+ void init_002()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+
+ sal_uInt32 nKeyLen = 16;
+ sal_uInt8 *pKeyBuffer = new sal_uInt8[ nKeyLen ];
+ memset(pKeyBuffer, 0, nKeyLen);
+ pKeyBuffer[0] = 1;
+
+ sal_uInt32 nArgLen = 16;
+ sal_uInt8 *pArgBuffer = new sal_uInt8[ nArgLen ];
+ memset(pArgBuffer, 0, nArgLen);
+
+ rtlCipherError aError = rtl_cipher_init(aCipher, rtl_Cipher_DirectionEncode, pKeyBuffer, nKeyLen, pArgBuffer, nArgLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong init", rtl_Cipher_E_None, aError);
+
+ delete [] pArgBuffer;
+ delete [] pKeyBuffer;
+
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ void init_003()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+
+ sal_uInt32 nKeyLen = 16;
+ sal_uInt8 *pKeyBuffer = new sal_uInt8[ nKeyLen ];
+ memset(pKeyBuffer, 0, nKeyLen);
+
+ sal_uInt32 nArgLen = 16;
+ sal_uInt8 *pArgBuffer = new sal_uInt8[ nArgLen ];
+ memset(pArgBuffer, 0, nArgLen);
+ pArgBuffer[0] = 1;
+
+ rtlCipherError aError = rtl_cipher_init(aCipher, rtl_Cipher_DirectionEncode, pKeyBuffer, nKeyLen, pArgBuffer, nArgLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong init", rtl_Cipher_E_None, aError);
+
+ delete [] pArgBuffer;
+ delete [] pKeyBuffer;
+
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ void init_004()
+ {
+ rtlCipher aCipher = rtl_cipher_create(rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeECB);
+#if defined LIBO_CIPHER_OPENSSL_BACKEND
+ CPPUNIT_ASSERT_EQUAL(rtlCipher(nullptr), aCipher);
+#else
+ CPPUNIT_ASSERT_MESSAGE("create failed.", aCipher != nullptr);
+
+ sal_uInt32 nKeyLen = 16;
+ sal_uInt8 *pKeyBuffer = new sal_uInt8[ nKeyLen ];
+ memset(pKeyBuffer, 0, nKeyLen);
+ pKeyBuffer[0] = 1;
+
+ sal_uInt32 nArgLen = 16;
+ sal_uInt8 *pArgBuffer = new sal_uInt8[ nArgLen ];
+ memset(pArgBuffer, 0, nArgLen);
+ pArgBuffer[0] = 1;
+
+ rtlCipherError aError = rtl_cipher_init(aCipher, rtl_Cipher_DirectionEncode, pKeyBuffer, nKeyLen, pArgBuffer, nArgLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong init", rtl_Cipher_E_None, aError);
+
+ delete [] pArgBuffer;
+ delete [] pKeyBuffer;
+
+ rtl_cipher_destroy(aCipher);
+#endif
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(init);
+ CPPUNIT_TEST(init_001);
+ CPPUNIT_TEST(init_002);
+ CPPUNIT_TEST(init_003);
+ CPPUNIT_TEST(init_004);
+ CPPUNIT_TEST_SUITE_END();
+}; // class init
+
+class initBF : public CppUnit::TestFixture
+{
+public:
+
+ void initBF_001()
+ {
+ // seems to be the same as init, so empty
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(initBF);
+ CPPUNIT_TEST(initBF_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class initBF
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::create);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::createBF);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::decode);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::decodeBF);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::destroy);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::destroyBF);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::encode);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::encodeBF);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::init);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_cipher::initBF);
+
+} // namespace rtl_cipher
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/crc32/rtl_crc32.cxx b/sal/qa/rtl/crc32/rtl_crc32.cxx
new file mode 100644
index 000000000..00933b589
--- /dev/null
+++ b/sal/qa/rtl/crc32/rtl_crc32.cxx
@@ -0,0 +1,154 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/crc.h>
+
+namespace rtl_CRC32
+{
+
+class test : public CppUnit::TestFixture
+{
+public:
+
+ // insert your test code here.
+ void rtl_crc32_001()
+ {
+ // this is demonstration code
+ // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1);
+
+ sal_uInt32 nCRC = 0;
+
+ char buf[] = {0};
+ int num = 0;
+
+ nCRC = rtl_crc32(nCRC, buf, num);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("empty crc buffer", static_cast<sal_uInt32>(0), nCRC);
+ }
+
+ void rtl_crc32_002()
+ {
+ sal_uInt32 nCRC = 0;
+
+ char buf[] = {0,0};
+ int num = sizeof(buf);
+
+ nCRC = rtl_crc32(nCRC, buf, num);
+
+ CPPUNIT_ASSERT_MESSAGE("buffer contain 2 empty bytes, crc is zero", nCRC != 0);
+ }
+
+ void rtl_crc32_002_1()
+ {
+ sal_uInt32 nCRC = 0;
+
+ char buf[] = {0,0,0};
+ int num = sizeof(buf);
+
+ nCRC = rtl_crc32(nCRC, buf, num);
+
+ CPPUNIT_ASSERT_MESSAGE("buffer contain 3 empty bytes, crc is zero", nCRC != 0);
+ }
+
+ /**
+ * crc32 check:
+ * Build checksum on two buffers with same size but different content,
+ * the result (crc32 checksum) must differ
+ */
+
+ void rtl_crc32_003()
+ {
+ sal_uInt32 nCRC1 = 0;
+ char buf1[] = {2};
+ int num1 = sizeof(buf1);
+
+ nCRC1 = rtl_crc32(nCRC1, buf1, num1);
+
+ sal_uInt32 nCRC2 = 0;
+ char buf2[] = {3};
+ int num2 = sizeof(buf2);
+
+ nCRC2 = rtl_crc32(nCRC2, buf2, num2);
+
+ CPPUNIT_ASSERT_MESSAGE("checksum should differ for buf1 and buf2", nCRC1 != nCRC2);
+ }
+
+ /** check if the crc32 only use as much values, as given
+ *
+ */
+ void rtl_crc32_003_1()
+ {
+ sal_uInt32 nCRC1 = 0;
+ char buf1[] = {2,1};
+ int num1 = sizeof(buf1) - 1;
+
+ nCRC1 = rtl_crc32(nCRC1, buf1, num1);
+
+ sal_uInt32 nCRC2 = 0;
+ char buf2[] = {2,2};
+ int num2 = sizeof(buf2) - 1;
+
+ nCRC2 = rtl_crc32(nCRC2, buf2, num2);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("checksum leave it's bounds", nCRC2, nCRC1);
+ }
+
+ /** check if the crc32 differ at same content in reverse order
+ *
+ */
+ void rtl_crc32_003_2()
+ {
+ sal_uInt32 nCRC1 = 0;
+ char buf1[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ int num1 = sizeof(buf1);
+
+ nCRC1 = rtl_crc32(nCRC1, buf1, num1);
+
+ sal_uInt32 nCRC2 = 0;
+ char buf2[] = {20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+ int num2 = sizeof(buf2);
+
+ nCRC2 = rtl_crc32(nCRC2, buf2, num2);
+
+ CPPUNIT_ASSERT_MESSAGE("checksum should differ", nCRC1 != nCRC2);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(test);
+ CPPUNIT_TEST(rtl_crc32_001);
+ CPPUNIT_TEST(rtl_crc32_002);
+ CPPUNIT_TEST(rtl_crc32_002_1);
+ CPPUNIT_TEST(rtl_crc32_003);
+ CPPUNIT_TEST(rtl_crc32_003_1);
+ CPPUNIT_TEST(rtl_crc32_003_2);
+ CPPUNIT_TEST_SUITE_END();
+}; // class test
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_CRC32::test);
+} // namespace rtl_CRC32
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/digest/rtl_digest.cxx b/sal/qa/rtl/digest/rtl_digest.cxx
new file mode 100644
index 000000000..4bf0512a0
--- /dev/null
+++ b/sal/qa/rtl/digest/rtl_digest.cxx
@@ -0,0 +1,515 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <memory>
+#include <string_view>
+
+#include <rtl/digest.h>
+#include <rtl/string.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <string.h>
+
+using namespace rtl;
+
+namespace
+{
+
+constexpr OStringLiteral sSampleString ("This is a sample sentence, which we use to check some crypto functions in sal.");
+constexpr OStringLiteral sSampleString_only_one_diff ("This is a sample sentence. which we use to check some crypto functions in sal.");
+
+const rtlDigestAlgorithm constDigestAlgorithms[] =
+{
+ rtl_Digest_AlgorithmMD2,
+ rtl_Digest_AlgorithmMD5,
+ rtl_Digest_AlgorithmSHA,
+ rtl_Digest_AlgorithmSHA1,
+ rtl_Digest_AlgorithmHMAC_MD5,
+ rtl_Digest_AlgorithmHMAC_SHA1,
+};
+
+const sal_uInt32 constDigestAlgorithmLengths[] =
+{
+ RTL_DIGEST_LENGTH_MD2,
+ RTL_DIGEST_LENGTH_MD5,
+ RTL_DIGEST_LENGTH_SHA,
+ RTL_DIGEST_LENGTH_SHA1,
+ RTL_DIGEST_LENGTH_HMAC_MD5,
+ RTL_DIGEST_LENGTH_HMAC_SHA1,
+};
+
+const std::string_view constSampleStringSums[] =
+{
+ std::string_view("647ee6c9d4aa5fdd374ed9d7a156acbf"),
+ std::string_view("b16b903e6fc0b62ae389013ed93fe531"),
+ std::string_view("eab2814429b2613301c8a077b806af3680548914"),
+ std::string_view("2bc5bdb7506a2cdc2fd27fc8b9889343012d5008"),
+ std::string_view("0b1b0e1a6f2e4420326354b031063605"),
+ std::string_view("1998c6a556915be76451bfb587fa7c34d849936e")
+};
+
+// Create hex-value string from the digest value to keep the string size minimal
+OString createHex(const sal_uInt8* pKeyBuffer, sal_uInt32 nKeyLen)
+{
+ OStringBuffer aBuffer(nKeyLen * 2 + 1);
+ for (sal_uInt32 i = 0; i < nKeyLen; ++i)
+ {
+ sal_Int32 nValue = static_cast<sal_Int32>(pKeyBuffer[i]);
+ if (nValue < 16)
+ aBuffer.append('0');
+ aBuffer.append(nValue, 16);
+ }
+ return aBuffer.makeStringAndClear();
+}
+
+OString getDigest(const OString& aMessage, rtlDigestAlgorithm aAlgorithm)
+{
+ rtlDigest handle = rtl_digest_create(aAlgorithm);
+
+ const sal_uInt8* pData = reinterpret_cast<const sal_uInt8*>(aMessage.getStr());
+ sal_uInt32 nSize = aMessage.getLength();
+
+ rtl_digest_init(handle, pData, nSize);
+ rtl_digest_update(handle, pData, nSize);
+
+ sal_uInt32 nKeyLen = rtl_digest_queryLength(handle);
+ std::unique_ptr<sal_uInt8[]> pKeyBuffer(new sal_uInt8[nKeyLen]);
+
+ rtl_digest_get(handle, pKeyBuffer.get(), nKeyLen);
+ OString aSum = createHex(pKeyBuffer.get(), nKeyLen);
+
+ rtl_digest_destroy( handle );
+ return aSum;
+}
+
+class DigestTest : public CppUnit::TestFixture
+{
+public:
+ void testCreate()
+ {
+ for (size_t i = 0; i < SAL_N_ELEMENTS(constDigestAlgorithms); i++)
+ {
+ rtlDigest handle = rtl_digest_create( constDigestAlgorithms[i] );
+ CPPUNIT_ASSERT_MESSAGE("create digest", handle != nullptr);
+ rtl_digest_destroy( handle );
+ }
+
+ rtlDigest handle = rtl_digest_create( rtl_Digest_AlgorithmInvalid );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("create invalid digest", static_cast<rtlDigest>(nullptr), handle);
+ rtl_digest_destroy( handle );
+ }
+
+ void testQuery()
+ {
+ for (size_t i = 0; i < SAL_N_ELEMENTS(constDigestAlgorithms); i++)
+ {
+ rtlDigest handle = rtl_digest_create(constDigestAlgorithms[i]);
+ rtlDigestAlgorithm aAlgo = rtl_digest_queryAlgorithm(handle);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("query handle", aAlgo, constDigestAlgorithms[i]);
+ rtl_digest_destroy( handle );
+ }
+
+ }
+
+ void testQueryLength()
+ {
+ rtlDigest handle;
+ sal_uInt32 nAlgoLength;
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(constDigestAlgorithms); i++)
+ {
+ handle = rtl_digest_create(constDigestAlgorithms[i]);
+ nAlgoLength = rtl_digest_queryLength(handle);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("query Length", nAlgoLength, constDigestAlgorithmLengths[i]);
+ rtl_digest_destroy( handle );
+ }
+
+ handle = rtl_digest_create( rtl_Digest_AlgorithmInvalid );
+ nAlgoLength = rtl_digest_queryLength(handle);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("query length", static_cast<sal_uInt32>(0), nAlgoLength);
+ rtl_digest_destroy( handle );
+ }
+
+ void testInit()
+ {
+ rtlDigestError aError;
+ rtlDigest handle;
+
+ handle = nullptr;
+ aError = rtl_digest_init(handle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("init(NULL, 0, 0)", rtl_Digest_E_Argument, aError);
+
+ handle = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ aError = rtl_digest_init(handle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("init(handle, 0, 0)", rtl_Digest_E_None, aError);
+ rtl_digest_destroy( handle );
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(constDigestAlgorithms); i++)
+ {
+ handle = rtl_digest_create(constDigestAlgorithms[i]);
+
+ OString aMessage = sSampleString;
+ const sal_uInt8* pData = reinterpret_cast<const sal_uInt8*>(aMessage.getStr());
+ sal_uInt32 nSize = aMessage.getLength();
+
+ aError = rtl_digest_init(handle, pData, nSize);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("init(handle, pData, nSize)", rtl_Digest_E_None, aError);
+
+ rtl_digest_update(handle, pData, nSize);
+
+ sal_uInt32 nKeyLen = rtl_digest_queryLength( handle );
+ std::unique_ptr<sal_uInt8[]> pKeyBuffer(new sal_uInt8[nKeyLen]);
+
+ rtl_digest_get( handle, pKeyBuffer.get(), nKeyLen );
+ createHex(pKeyBuffer.get(), nKeyLen);
+
+ rtl_digest_destroy( handle );
+ }
+ }
+
+ void testEqual()
+ {
+ {
+ OString aSum1 = getDigest(sSampleString, rtl_Digest_AlgorithmMD5);
+ OString aSum2 = getDigest(sSampleString, rtl_Digest_AlgorithmMD5);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "md5sum must have a length", sal_Int32(32), aSum1.getLength() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "md5sum must have a length", sal_Int32(32), aSum2.getLength() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("source is the same, dest must be also the same", aSum1, aSum2);
+ }
+
+ {
+ OString aSum1 = getDigest(sSampleString, rtl_Digest_AlgorithmMD5);
+ OString aSum2 = getDigest(sSampleString_only_one_diff, rtl_Digest_AlgorithmMD5);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "md5sum must have a length", sal_Int32(32), aSum1.getLength() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "md5sum must have a length", sal_Int32(32), aSum2.getLength() );
+ CPPUNIT_ASSERT_MESSAGE("differ only in one char", aSum1 != aSum2);
+ }
+ }
+
+ void testCheckSum()
+ {
+ for (size_t i = 0; i < SAL_N_ELEMENTS(constDigestAlgorithms); i++)
+ {
+ OString aSum = getDigest(sSampleString, constDigestAlgorithms[i]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Checksum of sample string is wrong.", OString(constSampleStringSums[i]), aSum);
+ }
+ }
+
+ OString runCheckPBKDF2(OString& sPassword, bool bClearSalt, sal_uInt32 nCount)
+ {
+ sal_uInt32 nKeyLen = RTL_DIGEST_LENGTH_HMAC_SHA1;
+ std::unique_ptr<sal_uInt8[]> pKeyBuffer(new sal_uInt8[nKeyLen]);
+
+ memset(pKeyBuffer.get(), 0, nKeyLen);
+
+ sal_uInt8 const * pPassword = reinterpret_cast<sal_uInt8 const *>(sPassword.getStr());
+ sal_Int32 nPasswordLen = sPassword.getLength();
+
+ sal_uInt32 nSaltDataLen = RTL_DIGEST_LENGTH_HMAC_SHA1;
+ std::unique_ptr<sal_uInt8[]> pSaltData(new sal_uInt8[nSaltDataLen]);
+ memset(pSaltData.get(), 0, nSaltDataLen);
+
+ if (!bClearSalt)
+ {
+ // wilful contamination
+ pSaltData[0] = 1;
+ }
+
+ rtlDigestError aError = rtl_digest_PBKDF2(pKeyBuffer.get(), nKeyLen, pPassword, nPasswordLen, pSaltData.get(), nSaltDataLen, nCount);
+
+ CPPUNIT_ASSERT_EQUAL(rtl_Digest_E_None, aError);
+
+ OString aKey = createHex(pKeyBuffer.get(), nKeyLen);
+
+ // OString sSalt = createHex(pSaltData, nSaltDataLen);
+ // printf("Salt: %s\n", sSalt.getStr());
+
+ // CPPUNIT_ASSERT_MESSAGE("md5sum of sample string is wrong. Code changes or sample problems, please check.", aStr.equals(sSampleString_PBKDF2) );
+ return aKey;
+ }
+
+ void testPBKDF2()
+ {
+ OString aPassword = "Password";
+
+ // all permutations
+ runCheckPBKDF2(aPassword, false, 1);
+ runCheckPBKDF2(aPassword, false, 2);
+ runCheckPBKDF2(aPassword, true, 1);
+ runCheckPBKDF2(aPassword, true, 2);
+ runCheckPBKDF2(aPassword, false, 3);
+ runCheckPBKDF2(aPassword, false, 4);
+ runCheckPBKDF2(aPassword, true, 3);
+ runCheckPBKDF2(aPassword, true, 4);
+ }
+
+ void testUpdate()
+ {
+ rtlDigestError aError;
+ rtlDigest aHandle;
+
+ aHandle = nullptr;
+ aError = rtl_digest_update(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
+
+ aHandle = nullptr;
+ aError = rtl_digest_updateMD2(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
+
+ aError = rtl_digest_updateMD5(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
+
+ aHandle = rtl_digest_create( rtl_Digest_AlgorithmMD2 );
+ CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD2", aHandle != nullptr);
+
+ const sal_uInt8* pData = reinterpret_cast<const sal_uInt8*>(sSampleString.getStr());
+ sal_uInt32 nSize = sSampleString.getLength();
+
+ aError = rtl_digest_updateMD2(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'pData' wrong", rtl_Digest_E_Argument, aError);
+
+ aError = rtl_digest_updateMD2(aHandle, pData, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'nSize' wrong", rtl_Digest_E_None, aError);
+
+ rtl_digest_destroyMD2(aHandle);
+
+ // use wrong Algorithm!!! This is volitional!
+ aHandle = rtl_digest_create(rtl_Digest_AlgorithmMD2);
+ CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD2", aHandle != nullptr);
+
+ aError = rtl_digest_updateMD5(aHandle, pData, nSize);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'handle' wrong", rtl_Digest_E_Algorithm, aError);
+
+ rtl_digest_destroyMD5(aHandle);
+
+ aHandle = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD5", aHandle != nullptr);
+
+ aError = rtl_digest_updateMD5(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'pData' wrong", rtl_Digest_E_Argument, aError);
+
+ aError = rtl_digest_updateMD5(aHandle, pData, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'nSize' wrong", rtl_Digest_E_None, aError);
+
+ rtl_digest_destroyMD5(aHandle);
+ }
+
+ void testGet()
+ {
+ rtlDigest aHandle;
+ rtlDigestError aError;
+
+ aHandle = nullptr;
+ aError = rtl_digest_get(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
+
+ aHandle = nullptr;
+ aError = rtl_digest_getMD5(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("does not handle wrong parameter", rtl_Digest_E_Argument, aError);
+
+ // test with wrong algorithm
+ aHandle = rtl_digest_create(rtl_Digest_AlgorithmMD2);
+ CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD2", aHandle != nullptr);
+
+ sal_uInt32 nKeyLen = rtl_digest_queryLength(aHandle);
+ std::unique_ptr<sal_uInt8[]> pKeyBuffer(new sal_uInt8[nKeyLen]);
+
+ aError = rtl_digest_getMD5(aHandle, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle 2. parameter wrong", rtl_Digest_E_Argument, aError);
+
+ aError = rtl_digest_getMD5(aHandle, pKeyBuffer.get(), 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'handle' wrong", rtl_Digest_E_Algorithm, aError);
+
+ rtl_digest_destroyMD2(aHandle);
+
+ aHandle = rtl_digest_create(rtl_Digest_AlgorithmMD5);
+ CPPUNIT_ASSERT_MESSAGE("create with rtl_Digest_AlgorithmMD5", aHandle != nullptr);
+
+ aError = rtl_digest_getMD5(aHandle, nullptr, nKeyLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'pData' wrong", rtl_Digest_E_Argument, aError);
+
+ aError = rtl_digest_getMD5(aHandle, pKeyBuffer.get(), 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("handle parameter 'nSize' wrong", rtl_Digest_E_BufferSize, aError);
+
+ rtl_digest_destroyMD5(aHandle);
+ }
+
+ void testSHA1SumForBiggerInputData()
+ {
+ // The test data was extracted from oox encrypted document (salt + password).
+ // First case: 16 bytes salt + 34 bytes password (12345678901234567)
+ // Second case: 16 bytes salt + 36 bytes password (123456789012345678)
+ {
+ const unsigned char aData[] = {
+ 0x37, 0x5f, 0x47, 0x7a, 0xd2, 0x13, 0xbe, 0xd2, 0x3c, 0x23, 0x33, 0x39,
+ 0x68, 0x21, 0x03, 0x6d, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
+ 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x30, 0x00,
+ 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00,
+ 0x37, 0x00
+ };
+
+ std::unique_ptr<sal_uInt8[]> pResult(new sal_uInt8[RTL_DIGEST_LENGTH_SHA1]);
+
+ rtl_digest_SHA1(aData, sizeof(aData), pResult.get(), RTL_DIGEST_LENGTH_SHA1);
+
+ OString sKey = createHex(pResult.get(), RTL_DIGEST_LENGTH_SHA1);
+
+ CPPUNIT_ASSERT_EQUAL(OString("06f460d693aecdd3b5cbe8365408eccfc570f32a"), sKey);
+ }
+
+ // tdf#114939, verify that rtl_digest_SHA1 computes broken results for certain input (which
+ // is not fixed for compatibility reasons):
+ {
+ sal_uInt8 result[RTL_DIGEST_LENGTH_SHA1];
+ rtl_digest_SHA1(
+ RTL_CONSTASCII_STRINGPARAM("1012345678901234567890123456789012345678901234567890"),
+ result, RTL_DIGEST_LENGTH_SHA1);
+ // Rather than correct "9cb1dab34448c1ea460da1f8736869c8852f212f":
+ CPPUNIT_ASSERT_EQUAL(
+ OString("90a461ee9cc69cedaeb25c2dc5cc62544ebd5241"),
+ createHex(result, RTL_DIGEST_LENGTH_SHA1));
+ }
+ }
+
+ void testMD5()
+ {
+ unsigned char const data[] = {
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ };
+ OString const expected[] = {
+ "d41d8cd98f00b204e9800998ecf8427e",
+ "cfcd208495d565ef66e7dff9f98764da",
+ "b4b147bc522828731f1a016bfa72c073",
+ "c6f057b86584942e415435ffb1fa93d4",
+ "4a7d1ed414474e4033ac29ccb8653d9b",
+ "dcddb75469b4b4875094e14561e573d8",
+ "670b14728ad9902aecba32e22fa4f6bd",
+ "29c3eea3f305d6b823f562ac4be35217",
+ "dd4b21e9ef71e1291183a46b913ae6f2",
+ "4c93008615c2d041e33ebac605d14b5b",
+ "f1b708bba17f1ce948dc979f4d7092bc",
+ "645a8aca5a5b84527c57ee2f153f1946",
+ "35b9ab5a36f3234dd26db357fd4a0dc1",
+ "4aad0d9ff11812ebdd5e376fdbef6222",
+ "c47532bbb1e2883c902071591ae1ec9b",
+ "5284047f4ffb4e04824a2fd1d1f0cd62",
+ "1e4a1b03d1b6cd8a174a826f76e009f4",
+ "0e7b9f29a828b6f953b482fc299e536b",
+ "3ea032bf79e8c116b05f4698d5a8e044",
+ "15f47c8a3e5e9685307dd65a653b8dc0",
+ "cc545187d0745132de1e9941db0ef6ce",
+ "0585e303e79acd837c3a3e2a2bec8b18",
+ "b28ccfdee4b9f39ba18b58a4f61a03d1",
+ "d018229b1183c926c10ea688350afec8",
+ "660719b4a7591769583a7c8d20c6dfa4",
+ "1e2432adacf481836265fcc62ee8f3e3",
+ "6e88e2af74c1d9d7d7d652b90d03751e",
+ "780ca685003cec1d617beaa6f346e1be",
+ "7f2e1dcfd6e2a3f5c38f31e640136ff6",
+ "1a3dee46117aeb8010cf365b8653faa8",
+ "1d0064395af3c745f6c3194e92373d7a",
+ "b52582043219f2deb2d3c9cb05d6448a",
+ "cd9e459ea708a948d5c2f5a6ca8838cf",
+ "00de800ecd7a4fb2813986c987e46d51",
+ "15336d4b38561a82bd24c9398b781aed",
+ "5fe699d3c461ab5a795505f59d5adf15",
+ "c5e0eb03cbb4bea95ce3f8f48fca77d5",
+ "355c1410373ef02fff2b03844d72c7d4",
+ "02df97da8207de2b3afa69c151ca8958",
+ "82c66dbf3e73f87ffc9564b2098d6a4f",
+ "b373e3ddc3438d7c10c76f3ad9d4c401",
+ "fac901a4a3dbc4461541731a33a31d15",
+ "f573e011b414bf3f9dd284f7dad29592",
+ "11694570cc5dda099669f2ba3660a70d",
+ "60997cc8aef7fedd9995e6b3ca89ce26",
+ "63c5fcf83c2275fe64e880dd8dfc5cd6",
+ "c7a0a100057ebbfc63ee169562026aea",
+ "42c2dec247919384edece38033458627",
+ "b505acf9fc996902b0c547a2abfc62b2",
+ "2fa7a1321d6b5fa0e04ad46785f574f3",
+ "86d2bfc0bab44eecf21e1432be7b3efc",
+ "7ca318f12a0955a3e637dc5645a2f96e",
+ "3eda02765b8fb8bb9b20c735f4537827",
+ "26dead12262c9a5c115b01e0a3c805b6",
+ "978b0444e93c5f7d714575f28a77dca1",
+ "d7fe636bd28e2ee2ba4d6c5898318699",
+ "ce992c2ad906967c63c3f9ab0c2294a9",
+ "1f3b814e9d417e9fd8750299982feb1f",
+ "1a2f42174eaa78ce6a67d75e98a59cb6",
+ "17c772c45c9a09f6e56b7228ddd161a7",
+ "5b19445b70b493c78f3bc06eb7962315",
+ "e590c24cc612bdedd522dfe23bb29b42",
+ "4d78c699a0167bc0cfce8a5c5a715c0e",
+ "5703db92acb9d45e3975822c9206453f",
+ "10eab6008d5642cf42abd2aa41f847cb",
+ };
+ rtlDigest digest = rtl_digest_createMD5();
+ for (size_t i = 0; i < sizeof(data); ++i)
+ {
+ rtl_digest_updateMD5(digest, &data, i);
+ sal_uInt8 buf[RTL_DIGEST_LENGTH_MD5];
+ rtl_digest_getMD5(digest, &buf[0], sizeof(buf));
+ OString const sResult = createHex(&buf[0], sizeof(buf));
+ CPPUNIT_ASSERT_EQUAL(expected[i], sResult);
+ }
+ rtl_digest_destroyMD5(digest);
+ }
+
+ CPPUNIT_TEST_SUITE(DigestTest);
+ CPPUNIT_TEST(testCreate);
+ CPPUNIT_TEST(testQuery);
+ CPPUNIT_TEST(testQueryLength);
+ CPPUNIT_TEST(testInit);
+ CPPUNIT_TEST(testEqual);
+ CPPUNIT_TEST(testCheckSum);
+ CPPUNIT_TEST(testPBKDF2);
+ CPPUNIT_TEST(testUpdate);
+ CPPUNIT_TEST(testGet);
+ CPPUNIT_TEST(testSHA1SumForBiggerInputData);
+ CPPUNIT_TEST(testMD5);
+
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DigestTest);
+
+} // namespace rtl_digest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/doublelock/rtl_doublelocking.cxx b/sal/qa/rtl/doublelock/rtl_doublelocking.cxx
new file mode 100644
index 000000000..ef639423d
--- /dev/null
+++ b/sal/qa/rtl/doublelock/rtl_doublelocking.cxx
@@ -0,0 +1,182 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <iostream>
+
+#include <sal/types.h>
+
+#include <osl/thread.hxx>
+
+#include <rtl/instance.hxx>
+#include <rtl/ustring.hxx>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#ifdef _WIN32
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <time.h>
+#endif
+
+#define CONST_TEST_STRING "gregorian"
+
+namespace {
+struct Gregorian : public rtl::StaticWithInit<OUString, Gregorian> {
+ OUString operator () () {
+ return CONST_TEST_STRING;
+ }
+};
+
+/** Simple thread for testing Thread-create.
+ * Just add 1 of value 0, and after running, result is 1.
+ */
+class OGetThread : public osl::Thread
+{
+ osl::Mutex m_mutex;
+ sal_Int32 m_nOK;
+ sal_Int32 m_nFails;
+
+ OUString m_sConstStr;
+public:
+ OGetThread()
+ :m_nOK(0),
+ m_nFails(0),
+ m_sConstStr(CONST_TEST_STRING)
+ {
+ }
+
+ sal_Int32 getOK() { osl::MutexGuard g(m_mutex); return m_nOK; }
+ sal_Int32 getFails() {osl::MutexGuard g(m_mutex); return m_nFails;}
+
+protected:
+
+ /** guarded value which initialized 0
+
+ @see ThreadSafeValue
+ */
+ void SAL_CALL run() override
+ {
+ for (int i = 0; i != 5; ++i)
+ {
+ OUString aStr = Gregorian::get();
+ if (aStr == m_sConstStr)
+ {
+ osl::MutexGuard g(m_mutex);
+ m_nOK++;
+ }
+ else
+ {
+ osl::MutexGuard g(m_mutex);
+ m_nFails++;
+ }
+ }
+ }
+
+public:
+
+ virtual ~OGetThread() override
+ {
+ if (isRunning())
+ {
+ printf("error: not terminated.\n");
+ }
+ }
+};
+
+}
+
+namespace rtl_DoubleLocking
+{
+
+/** Test of the osl::Thread::create method
+ */
+
+ class getValue : public CppUnit::TestFixture
+ {
+ public:
+
+ void getValue_001()
+ {
+ OUString aStr = Gregorian::get();
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Gregorian::get() failed, wrong value expected.",
+ !aStr.isEmpty()
+ );
+ }
+
+ /** check 2 threads.
+
+ ALGORITHM:
+ Here the function should show, that 2 different threads,
+ which only increase a value, should run at the same time with same prio.
+ The test fails, if the difference between the two values is more than 5%
+ but IMHO this isn't a failure, it's only a feature of the OS.
+ */
+
+ void getValue_002()
+ {
+ // initial 5 threads with different priorities
+ OGetThread* pThread = new OGetThread();
+ OGetThread* p2Thread = new OGetThread();
+
+ //Create them and start running at the same time
+ pThread->create();
+ p2Thread->create();
+
+ pThread->join();
+ p2Thread->join();
+
+ sal_Int32 nValueOK = pThread->getOK();
+
+ sal_Int32 nValueOK2 = p2Thread->getOK();
+
+ std::cout << "Value in Thread #1 is " << nValueOK << "\n";
+ std::cout << "Value in Thread #2 is " << nValueOK2 << "\n";
+ sal_Int32 nValueFails = pThread->getFails();
+
+ sal_Int32 nValueFails2 = p2Thread->getFails();
+
+ delete pThread;
+ delete p2Thread;
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nValueOK);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nValueOK2);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nValueFails);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nValueFails2);
+ }
+
+ CPPUNIT_TEST_SUITE(getValue);
+ CPPUNIT_TEST(getValue_001);
+ CPPUNIT_TEST(getValue_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class create
+
+ CPPUNIT_TEST_SUITE_REGISTRATION(rtl_DoubleLocking::getValue);
+} // namespace rtl_DoubleLocking
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/locale/rtl_locale.cxx b/sal/qa/rtl/locale/rtl_locale.cxx
new file mode 100644
index 000000000..27e30db9f
--- /dev/null
+++ b/sal/qa/rtl/locale/rtl_locale.cxx
@@ -0,0 +1,280 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <rtl/locale.h>
+#include <rtl/ustring.hxx>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+namespace rtl_locale
+{
+ // default locale for test purpose
+ static void setDefaultLocale()
+ {
+ rtl_locale_setDefault(OUString("de").getStr(), OUString("DE").getStr(), /* OUString() */ OUString("hochdeutsch").getStr() );
+ }
+
+class getDefault : public CppUnit::TestFixture
+{
+public:
+ // initialise your test code values here.
+ void setUp() override
+ {
+ // start message
+ rtl_locale::setDefaultLocale();
+ }
+
+ void getDefault_001()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ CPPUNIT_ASSERT_MESSAGE("locale must not null", pData != nullptr);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(getDefault);
+ CPPUNIT_TEST(getDefault_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getDefault
+
+class setDefault : public CppUnit::TestFixture
+{
+public:
+ // initialise your test code values here.
+ void setUp() override
+ {
+ // start message
+ rtl_locale::setDefaultLocale();
+ }
+
+ void tearDown() override
+ {
+ setDefaultLocale();
+ }
+
+ // insert your test code here.
+ void setDefault_001()
+ {
+ rtl_locale_setDefault(OUString("en").getStr(), OUString("US").getStr(), OUString().getStr());
+ rtl_Locale* pData = rtl_locale_getDefault();
+ CPPUNIT_ASSERT_MESSAGE("locale must not null", pData != nullptr);
+
+ // be sure to not GPF
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(setDefault);
+ CPPUNIT_TEST(setDefault_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class setDefault
+
+class getLanguage : public CppUnit::TestFixture
+{
+public:
+ // initialise your test code values here.
+ void setUp() override
+ {
+ // start message
+ rtl_locale::setDefaultLocale();
+ }
+
+ // insert your test code here.
+ void getLanguage_001()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ OUString suLanguage = pData->Language;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "locale language must be 'de'", OUString("de"), suLanguage );
+ }
+ void getLanguage_002()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ OUString suLanguage(rtl_locale_getLanguage(pData), SAL_NO_ACQUIRE);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "locale language must be 'de'", OUString("de"), suLanguage );
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(getLanguage);
+ CPPUNIT_TEST(getLanguage_001);
+ CPPUNIT_TEST(getLanguage_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getLanguage
+
+class getCountry : public CppUnit::TestFixture
+{
+public:
+ // initialise your test code values here.
+ void setUp() override
+ {
+ // start message
+ rtl_locale::setDefaultLocale();
+ }
+
+ // insert your test code here.
+ void getCountry_001()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ OUString suCountry = pData->Country;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "locale country must be 'DE'", OUString("DE"), suCountry );
+ }
+ void getCountry_002()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ OUString suCountry(rtl_locale_getCountry(pData), SAL_NO_ACQUIRE);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "locale country must be 'DE'", OUString("DE"), suCountry );
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(getCountry);
+ CPPUNIT_TEST(getCountry_001);
+ CPPUNIT_TEST(getCountry_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getCountry
+
+class getVariant : public CppUnit::TestFixture
+{
+public:
+ // initialise your test code values here.
+ void setUp() override
+ {
+ // start message
+ rtl_locale::setDefaultLocale();
+ }
+
+ // insert your test code here.
+ void getVariant_001()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ OUString suVariant = pData->Variant;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "locale variant must be 'hochdeutsch'", OUString("hochdeutsch"), suVariant );
+ }
+ void getVariant_002()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ OUString suVariant(rtl_locale_getVariant(pData), SAL_NO_ACQUIRE);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "locale variant must be 'hochdeutsch'", OUString("hochdeutsch"), suVariant );
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(getVariant);
+ CPPUNIT_TEST(getVariant_001);
+ CPPUNIT_TEST(getVariant_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getVariant
+
+class hashCode : public CppUnit::TestFixture
+{
+public:
+ // initialise your test code values here.
+ void setUp() override
+ {
+ // start message
+ rtl_locale::setDefaultLocale();
+ }
+
+ // insert your test code here.
+ void hashCode_001()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ sal_Int32 nHashCode = pData->HashCode;
+ CPPUNIT_ASSERT_MESSAGE("locale hashcode must be 3831", nHashCode != 0);
+ }
+ void hashCode_002()
+ {
+ rtl_Locale* pData = rtl_locale_getDefault();
+ sal_Int32 nHashCode = rtl_locale_hashCode(pData);
+ CPPUNIT_ASSERT_MESSAGE("locale hashcode must be 3831", nHashCode != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(hashCode);
+ CPPUNIT_TEST(hashCode_001);
+ CPPUNIT_TEST(hashCode_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class hashCode
+
+class equals : public CppUnit::TestFixture
+{
+public:
+ // initialise your test code values here.
+ void setUp() override
+ {
+ // start message
+ rtl_locale::setDefaultLocale();
+ }
+
+ // insert your test code here.
+ void equals_001()
+ {
+ rtl_Locale* pData1 = rtl_locale_register(OUString("en").getStr(), OUString("US").getStr(), OUString().getStr());
+ rtl_Locale* pData2 = rtl_locale_register(OUString("en").getStr(), OUString("US").getStr(), OUString().getStr());
+
+ bool bLocaleAreEqual = (pData1 == pData2);
+
+ CPPUNIT_ASSERT_MESSAGE("check operator ==()", bLocaleAreEqual);
+ }
+
+ void equals_002()
+ {
+ rtl_Locale* pData1 = rtl_locale_register(OUString("en").getStr(), OUString("US").getStr(), OUString().getStr());
+ rtl_Locale* pData2 = rtl_locale_register(OUString("en").getStr(), OUString("US").getStr(), OUString().getStr());
+
+ sal_Int32 nEqual = rtl_locale_equals(pData1, pData2);
+ CPPUNIT_ASSERT(nEqual != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(equals);
+ CPPUNIT_TEST(equals_001);
+ CPPUNIT_TEST(equals_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class equals
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getDefault);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::setDefault);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getLanguage);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getCountry);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getVariant);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::hashCode);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::equals);
+} // namespace rtl_locale
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/math/test-rtl-math.cxx b/sal/qa/rtl/math/test-rtl-math.cxx
new file mode 100644
index 000000000..ee4ae55a1
--- /dev/null
+++ b/sal/qa/rtl/math/test-rtl-math.cxx
@@ -0,0 +1,677 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <rtl/math.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <limits>
+
+CPPUNIT_NS_BEGIN
+
+template<> struct assertion_traits<rtl_math_ConversionStatus>
+{
+ static bool equal( const rtl_math_ConversionStatus& x, const rtl_math_ConversionStatus& y )
+ {
+ return x == y;
+ }
+
+ static std::string toString( const rtl_math_ConversionStatus& x )
+ {
+ OStringStream ost;
+ ost << static_cast<unsigned int>(x);
+ return ost.str();
+ }
+};
+
+CPPUNIT_NS_END
+
+namespace {
+
+class Test: public CppUnit::TestFixture {
+public:
+ void test_stringToDouble_good() {
+ rtl_math_ConversionStatus status;
+ sal_Int32 end;
+ double res = rtl::math::stringToDouble(
+ " +1.E01foo",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(RTL_CONSTASCII_LENGTH(" +1.E01"), end);
+ CPPUNIT_ASSERT_EQUAL(10.0, res);
+
+ res = rtl::math::stringToDouble(
+ "NaN",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), end);
+ CPPUNIT_ASSERT(std::isnan(res));
+
+ res = rtl::math::stringToDouble(
+ "NaN1.23",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), end);
+ CPPUNIT_ASSERT(std::isnan(res));
+
+ res = rtl::math::stringToDouble(
+ "+NaN",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ res = rtl::math::stringToDouble(
+ "-NaN",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ res = rtl::math::stringToDouble(
+ "+1.#NAN",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(7), end);
+ CPPUNIT_ASSERT(std::isnan(res));
+ CPPUNIT_ASSERT(!std::signbit(res));
+
+ res = rtl::math::stringToDouble(
+ "-1.#NAN",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(7), end);
+ CPPUNIT_ASSERT(std::isnan(res));
+ CPPUNIT_ASSERT(std::signbit(res));
+
+ res = rtl::math::stringToDouble(
+ "INF",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_OutOfRange, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), end);
+ CPPUNIT_ASSERT(std::isinf(res));
+
+ res = rtl::math::stringToDouble(
+ "INF1.23",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_OutOfRange, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), end);
+ CPPUNIT_ASSERT(std::isinf(res));
+
+ res = rtl::math::stringToDouble(
+ ".5",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), end);
+ CPPUNIT_ASSERT_EQUAL(0.5, res);
+
+ res = rtl::math::stringToDouble(
+ "5.",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), end);
+ CPPUNIT_ASSERT_EQUAL(5.0, res);
+
+ // Leading 0 and group separator.
+ res = rtl::math::stringToDouble(
+ "0,123",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), end);
+ CPPUNIT_ASSERT_EQUAL(123.0, res);
+
+ // Leading 0 and two consecutive group separators are none.
+ res = rtl::math::stringToDouble(
+ "0,,1",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ // Leading 0 and group separator at end is none.
+ res = rtl::math::stringToDouble(
+ "0,",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ // Leading 0 and group separator before non-digit is none.
+ res = rtl::math::stringToDouble(
+ "0,x",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ // Trailing group separator is none.
+ res = rtl::math::stringToDouble(
+ "1,234,",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), end);
+ CPPUNIT_ASSERT_EQUAL(1234.0, res);
+
+ // Group separator followed by non-digit is none.
+ res = rtl::math::stringToDouble(
+ "1,234,x",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), end);
+ CPPUNIT_ASSERT_EQUAL(1234.0, res);
+
+ // Check that the value is the nearest double-precision representation of the decimal 0.0042
+ // (it was 0.0042000000000000006 instead of 0.0041999999999999997)
+ res = rtl::math::stringToDouble("0,0042", ',', ' ', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(0.0042, res);
+
+ // "- 1" is nothing
+ res = rtl::math::stringToDouble("- 1", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ // "-1E+E" : no exponent
+ res = rtl::math::stringToDouble("-1E+E", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), end);
+ CPPUNIT_ASSERT_EQUAL(-1.0, res);
+
+ // "-0" is negative zero
+ res = rtl::math::stringToDouble("-0", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+ CPPUNIT_ASSERT(std::signbit(res));
+
+ // Compensating: "0.001E311" is 1E308, not overflow/inf
+ res = rtl::math::stringToDouble("0.001E311", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(9), end);
+ CPPUNIT_ASSERT_EQUAL(1E308, res);
+
+ res = rtl::math::stringToDouble("1E8589934590", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_OutOfRange, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(12), end);
+ CPPUNIT_ASSERT_EQUAL(std::numeric_limits<double>::infinity(), res);
+
+ // DBL_MAX and 4 nextafters
+ double fValAfter = DBL_MAX;
+ res = rtl::math::stringToDouble("1.7976931348623157e+308", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(23), end);
+ CPPUNIT_ASSERT_EQUAL(fValAfter, res);
+
+ fValAfter = std::nextafter( fValAfter, 0);
+ res = rtl::math::stringToDouble("1.7976931348623155e+308", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(23), end);
+ CPPUNIT_ASSERT_EQUAL(fValAfter, res);
+
+ fValAfter = std::nextafter( fValAfter, 0);
+ res = rtl::math::stringToDouble("1.7976931348623153e+308", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(23), end);
+ CPPUNIT_ASSERT_EQUAL(fValAfter, res);
+
+ fValAfter = std::nextafter( fValAfter, 0);
+ res = rtl::math::stringToDouble("1.7976931348623151e+308", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(23), end);
+ CPPUNIT_ASSERT_EQUAL(fValAfter, res);
+
+ fValAfter = std::nextafter( fValAfter, 0);
+ res = rtl::math::stringToDouble("1.7976931348623149e+308", '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(23), end);
+ CPPUNIT_ASSERT_EQUAL(fValAfter, res);
+ }
+
+ void test_stringToDouble_bad() {
+ rtl_math_ConversionStatus status;
+ sal_Int32 end;
+ double res = rtl::math::stringToDouble(
+ " +Efoo",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ res = rtl::math::stringToDouble(
+ ".",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ res = rtl::math::stringToDouble(
+ " +.Efoo",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ res = rtl::math::stringToDouble(
+ " +,.Efoo",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+
+ // Leading group separator is none.
+ res = rtl::math::stringToDouble(
+ ",1234",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+ }
+
+ void test_stringToDouble_exponent_without_digit() {
+ rtl_math_ConversionStatus status;
+ sal_Int32 end;
+ double res = rtl::math::stringToDouble(
+ "1e",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(RTL_CONSTASCII_LENGTH("1"), end);
+ CPPUNIT_ASSERT_EQUAL(1.0, res);
+ res = rtl::math::stringToDouble(
+ "0e",
+ '.', ',', &status, &end);
+ CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+ CPPUNIT_ASSERT_EQUAL(RTL_CONSTASCII_LENGTH("1"), end);
+ CPPUNIT_ASSERT_EQUAL(0.0, res);
+ }
+
+ void test_round() {
+ double fVal = 5000000000000001.0;
+ CPPUNIT_ASSERT_EQUAL( 5000000000000001.0, rtl::math::round( fVal, 9, rtl_math_RoundingMode_Corrected));
+
+ fVal = 8796093022188.0;
+ CPPUNIT_ASSERT_EQUAL( 6093022188.0 , rtl::math::round( fVal, 9, rtl_math_RoundingMode_Corrected) - 8790000000000);
+
+ fVal = 4503599627370491.0;
+ CPPUNIT_ASSERT_EQUAL( 4503599627370000.0, rtl::math::round( fVal, -3, rtl_math_RoundingMode_Corrected));
+ }
+
+ void test_doubleToString() {
+ double fVal = 999999999999999.0;
+ sal_Int32 aGroups[3] = { 3, 2, 0 };
+ OUString aRes( rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max,
+ '.', aGroups, ',', true));
+ CPPUNIT_ASSERT_EQUAL( OUString("99,99,99,99,99,99,999"), aRes);
+
+ fVal = 949.0;
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ -2, // round before decimals
+ '.', aGroups, ',', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("900"), aRes);
+
+ fVal = 950.0;
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ -2, // round before decimals
+ '.', aGroups, ',', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1,000"), aRes);
+
+ fVal = 4503599627370495.0;
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.');
+ CPPUNIT_ASSERT_EQUAL( OUString("4503599627370495"), aRes);
+
+ fVal = 4503599627370496.0;
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ 2, '.');
+ CPPUNIT_ASSERT_EQUAL( OUString("4503599627370496.00"), aRes);
+
+ fVal = -4503599627370496.0;
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ 2, '.');
+ CPPUNIT_ASSERT_EQUAL( OUString("-4503599627370496.00"), aRes);
+
+ fVal = 9007199254740991.0; // (2^53)-1
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("9007199254740991"), aRes);
+
+ fVal = 9007199254740992.0; // (2^53), algorithm switch
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("9.00719925474099E+015"), aRes);
+
+ fVal = 9007199254740993.0; // (2^53)+1 would be but is 9007199254740992
+ aRes = rtl::math::doubleToUString( fVal,
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("9.00719925474099E+015"), aRes);
+
+ // Test rtl_math_StringFormat_G
+
+ fVal = 0.001234567;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 3, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("0.00123"), aRes);
+
+ fVal = 123.4567;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 3, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("123"), aRes);
+
+ fVal = 123.4567;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 4, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("123.5"), aRes);
+
+ fVal = 99.6;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 3, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("99.6"), aRes);
+
+ // Expected could be 1E+03 (as 999.6 rounded to 3 significant digits
+ // results in 1000 with an exponent equal to significant digits).
+ // Currently we don't and output 1000 instead, negligible.
+ fVal = 999.6;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 3, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1000"), aRes);
+
+ fVal = 9999.6;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 3, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1E+004"), aRes);
+
+ fVal = 12345.6789;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, -3, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.2E+004"), aRes);
+
+ // DBL_MAX and 4 nextafters
+ fVal = DBL_MAX;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.7976931348623157E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.7976931348623155E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.7976931348623153E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.7976931348623151E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.797693134862315E+308"), aRes);
+ CPPUNIT_ASSERT_EQUAL(fVal, rtl::math::stringToDouble(aRes, '.', ',')); // Test roundtrip
+
+ // DBL_MAX and 4 nextafters rounded to 15 decimals
+ fVal = DBL_MAX;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 15, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.797693134862316E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 15, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.797693134862316E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 15, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.797693134862315E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 15, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.797693134862315E+308"), aRes);
+
+ fVal = std::nextafter( fVal, 0);
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 15, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.797693134862315E+308"), aRes);
+
+ // DBL_MAX rounded to 14 decimals
+ fVal = DBL_MAX;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 14, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.79769313486232E+308"), aRes);
+
+ // DBL_MAX rounded to 2 decimals
+ fVal = DBL_MAX;
+ aRes = rtl::math::doubleToUString( fVal, rtl_math_StringFormat_Automatic, 2, '.', true);
+ CPPUNIT_ASSERT_EQUAL( OUString("1.8E+308"), aRes);
+
+ // Crashed after commit eae24a9488814e77254d175c11fc4a138c1dbd30
+ fVal = 123456.789;
+ aRes = rtl::math::doubleToUString(fVal, rtl_math_StringFormat_E, 2, '.', false);
+ CPPUNIT_ASSERT_EQUAL(OUString("1.23E+005"), aRes);
+
+ fVal = 9.9999999999999929;
+ aRes = rtl::math::doubleToUString(fVal, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL(OUString("9.99999999999999"), aRes);
+
+ fVal = 0.99999999999999933;
+ aRes = rtl::math::doubleToUString(fVal, rtl_math_StringFormat_F, rtl_math_DecimalPlaces_Max, '.', true);
+ CPPUNIT_ASSERT_EQUAL(OUString("0.999999999999999"), aRes);
+ }
+
+ void test_approx() {
+ // (2^53)-1 , (2^53)-3
+ CPPUNIT_ASSERT_EQUAL( false, rtl::math::approxEqual( 9007199254740991.0, 9007199254740989.0));
+ // (2^53)-1 , (2^53)-2
+ CPPUNIT_ASSERT_EQUAL( false, rtl::math::approxEqual( 9007199254740991.0, 9007199254740990.0));
+ // Note: the following are internally represented as 900719925474099.12
+ // and 900719925474098.88 and the difference is 0.25 ...
+ CPPUNIT_ASSERT_EQUAL( true, rtl::math::approxEqual( 900719925474099.1, 900719925474098.9));
+ CPPUNIT_ASSERT_EQUAL( true, rtl::math::approxEqual( 72.944444444444443, 72.9444444444444));
+ CPPUNIT_ASSERT_EQUAL( true, rtl::math::approxEqual( 359650.27322404372, 359650.27322404401));
+ CPPUNIT_ASSERT_EQUAL( true, rtl::math::approxEqual( 5.3590326375710063e+238, 5.3590326375710109e+238));
+ CPPUNIT_ASSERT_EQUAL( true, rtl::math::approxEqual( 7.4124095894894475e+158, 7.4124095894894514e+158));
+ CPPUNIT_ASSERT_EQUAL( true, rtl::math::approxEqual( 1.2905754687023132e+79, 1.2905754687023098e+79));
+ CPPUNIT_ASSERT_EQUAL( true, rtl::math::approxEqual( 3.5612905090455637e+38, 3.5612905090455599e+38));
+ // 0.3 - 0.2 - 0.1 == 0.0
+ CPPUNIT_ASSERT_EQUAL( 0.0, rtl::math::approxSub( rtl::math::approxSub( 0.3, 0.2), 0.1));
+ // ((2^53)-1) - ((2^53)-2) == 1.0
+ CPPUNIT_ASSERT_EQUAL( 1.0, rtl::math::approxSub( 9007199254740991.0, 9007199254740990.0));
+ // (3^31) - ((3^31)-1) == 1.0
+ CPPUNIT_ASSERT_EQUAL( 1.0, rtl::math::approxSub( 617673396283947.0, 617673396283946.0));
+ }
+
+ void test_erf() {
+ double x, res;
+ x = 0.0;
+ res = rtl::math::erf(x);
+ CPPUNIT_ASSERT_EQUAL(0.0,res);
+ rtl::math::setInf( &x, false);
+ res = rtl::math::erf(x);
+ CPPUNIT_ASSERT_EQUAL(1.0,res);
+ rtl::math::setInf( &x, true);
+ res = rtl::math::erf(x);
+ CPPUNIT_ASSERT_EQUAL(-1.0,res);
+ rtl::math::setNan( &x);
+ res = rtl::math::erf(x);
+ CPPUNIT_ASSERT(std::isnan(res));
+ x = 3.0;
+ res = rtl::math::erf(-x);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( -rtl::math::erf(x), res, 1E-12);
+ }
+
+ void test_erfc() {
+ double x, res;
+ x = 0.0;
+ res = rtl::math::erfc(x);
+ CPPUNIT_ASSERT_EQUAL(1.0,res);
+ rtl::math::setInf( &x, false);
+ res = rtl::math::erfc(x);
+ CPPUNIT_ASSERT_EQUAL(0.0,res);
+ rtl::math::setInf( &x, true);
+ res = rtl::math::erfc(x);
+ CPPUNIT_ASSERT_EQUAL(2.0,res);
+ rtl::math::setNan( &x);
+ res = rtl::math::erfc(x);
+ CPPUNIT_ASSERT(std::isnan(res));
+ x = 3.0;
+ res = rtl::math::erfc(-x);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 2.0 - rtl::math::erfc(x), res, 1E-12);
+ }
+
+ void test_expm1() {
+ double x, res;
+ x = 0.0;
+ res = rtl::math::expm1(x);
+ CPPUNIT_ASSERT_EQUAL(0.0,res);
+ x = -0.0;
+ res = rtl::math::expm1(x);
+ CPPUNIT_ASSERT_EQUAL(-0.0,res);
+ CPPUNIT_ASSERT(std::signbit(res));
+ rtl::math::setInf( &x, false);
+ res = rtl::math::expm1(x);
+ CPPUNIT_ASSERT_EQUAL(true, std::isinf(res) && !std::signbit(res));
+ rtl::math::setInf( &x, true);
+ res = rtl::math::expm1(x);
+ CPPUNIT_ASSERT_EQUAL(-1.0,res);
+ rtl::math::setNan( &x);
+ res = rtl::math::expm1(x);
+ CPPUNIT_ASSERT(std::isnan(res));
+ }
+
+ void test_log1p() {
+ double x, res;
+ x = 0.0;
+ res = rtl::math::log1p(x);
+ CPPUNIT_ASSERT_EQUAL(0.0,res);
+ x = -0.0;
+ res = rtl::math::log1p(x);
+ CPPUNIT_ASSERT_EQUAL(-0.0,res);
+ CPPUNIT_ASSERT(std::signbit(res));
+ rtl::math::setInf( &x, false);
+ res = rtl::math::log1p(x);
+ CPPUNIT_ASSERT_EQUAL(true, std::isinf(res) && !std::signbit(res));
+ x = -1.0;
+ res = rtl::math::log1p(x);
+ CPPUNIT_ASSERT_EQUAL(true, std::isinf(res) && std::signbit(res));
+ x = -1.1;
+ res = rtl::math::log1p(x);
+ CPPUNIT_ASSERT(std::isnan(res));
+ rtl::math::setInf( &x, true);
+ res = rtl::math::log1p(x);
+ CPPUNIT_ASSERT(std::isnan(res));
+ rtl::math::setNan( &x);
+ res = rtl::math::log1p(x);
+ CPPUNIT_ASSERT(std::isnan(res));
+ }
+
+ void test_acosh() {
+ double res;
+
+ res = rtl::math::acosh(-1.0); // NaN
+ CPPUNIT_ASSERT(std::isnan(res));
+
+ res = rtl::math::acosh(0.0); // NaN
+ CPPUNIT_ASSERT(std::isnan(res));
+
+ res = rtl::math::acosh(0.5); // NaN
+ CPPUNIT_ASSERT(std::isnan(res));
+
+ CPPUNIT_ASSERT_EQUAL(0.0, rtl::math::acosh(1.0));
+
+ res = rtl::math::acosh(std::numeric_limits<double>::infinity()); // +Inf
+ CPPUNIT_ASSERT(!std::signbit(res));
+ CPPUNIT_ASSERT(std::isinf(res));
+
+ // #i97605
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(692.56728736744176, rtl::math::acosh(3e+300), 1e-15);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.014142017775252324, rtl::math::acosh(1.0001), 1e-15);
+ }
+
+ void test_asinh() {
+ double res;
+
+ res = rtl::math::asinh(-std::numeric_limits<double>::infinity()); // -Inf
+ CPPUNIT_ASSERT(std::signbit(res));
+ CPPUNIT_ASSERT(std::isinf(res));
+
+ CPPUNIT_ASSERT_EQUAL(0.0, rtl::math::asinh(0.0));
+
+ res = rtl::math::asinh(std::numeric_limits<double>::infinity()); // +Inf
+ CPPUNIT_ASSERT(!std::signbit(res));
+ CPPUNIT_ASSERT(std::isinf(res));
+
+ // #i97605
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(691.67568924815798, rtl::math::asinh(1.23e+300), 1e-15);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0350378961923076, rtl::math::asinh(1.23), 1e-16);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.23e-300, rtl::math::asinh(1.23e-300), 1e-303);
+
+ // asinh is an odd function
+ CPPUNIT_ASSERT_EQUAL(-rtl::math::asinh(1.23e+300), rtl::math::asinh(-1.23e+300));
+ CPPUNIT_ASSERT_EQUAL(-rtl::math::asinh(1.23), rtl::math::asinh(-1.23));
+ CPPUNIT_ASSERT_EQUAL(-rtl::math::asinh(1.23e-300), rtl::math::asinh(-1.23e-300));
+ }
+
+ void test_atanh() {
+ double res;
+
+ res = rtl::math::atanh(-2.0); // NaN
+ CPPUNIT_ASSERT(std::isnan(res));
+
+ res = rtl::math::atanh(-1.0); // -Inf
+ CPPUNIT_ASSERT(std::signbit(res));
+ CPPUNIT_ASSERT(std::isinf(res));
+
+ CPPUNIT_ASSERT_EQUAL(0.0, rtl::math::atanh(0.0));
+
+ res = rtl::math::atanh(1.0); // +Inf
+ CPPUNIT_ASSERT(!std::signbit(res));
+ CPPUNIT_ASSERT(std::isinf(res));
+
+ res = rtl::math::atanh(2.0); // NaN
+ CPPUNIT_ASSERT(std::isnan(res));
+ }
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(test_stringToDouble_good);
+ CPPUNIT_TEST(test_stringToDouble_bad);
+ CPPUNIT_TEST(test_stringToDouble_exponent_without_digit);
+ CPPUNIT_TEST(test_round);
+ CPPUNIT_TEST(test_doubleToString);
+ CPPUNIT_TEST(test_erf);
+ CPPUNIT_TEST(test_erfc);
+ CPPUNIT_TEST(test_expm1);
+ CPPUNIT_TEST(test_log1p);
+ CPPUNIT_TEST(test_approx);
+ CPPUNIT_TEST(test_acosh);
+ CPPUNIT_TEST(test_asinh);
+ CPPUNIT_TEST(test_atanh);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/ostring/rtl_OString2.cxx b/sal/qa/rtl/ostring/rtl_OString2.cxx
new file mode 100644
index 000000000..204475084
--- /dev/null
+++ b/sal/qa/rtl/ostring/rtl_OString2.cxx
@@ -0,0 +1,508 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/string.hxx>
+
+#include "valueequal.hxx"
+
+namespace rtl_OString
+{
+
+class valueOf : public CppUnit::TestFixture
+{
+ void valueOf_float_test_impl(float _nValue)
+ {
+ OString sValue;
+ sValue = OString::valueOf( _nValue );
+ printf("nFloat := %.9f sValue := %s\n", _nValue, sValue.getStr());
+
+ float nValueATOF = static_cast<float>(atof( sValue.getStr() ));
+
+ bool bEqualResult = is_float_equal(_nValue, nValueATOF);
+ CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
+ }
+
+ void valueOf_float_test(float _nValue)
+ {
+ valueOf_float_test_impl(_nValue);
+
+ // test also the negative part.
+ float nNegativeValue = -_nValue;
+ valueOf_float_test_impl(nNegativeValue);
+ }
+
+public:
+ // insert your test code here.
+ void valueOf_float_test_001()
+ {
+ // this is demonstration code
+ // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1);
+ float nValue = 3.0f;
+ valueOf_float_test(nValue);
+ }
+
+ void valueOf_float_test_002()
+ {
+ float nValue = 3.5f;
+ valueOf_float_test(nValue);
+ }
+
+ void valueOf_float_test_003()
+ {
+ float nValue = 3.0625f;
+ valueOf_float_test(nValue);
+ }
+
+ void valueOf_float_test_004()
+ {
+ float nValue = 3.502525f;
+ valueOf_float_test(nValue);
+ }
+
+ void valueOf_float_test_005()
+ {
+ float nValue = 3.141592f;
+ valueOf_float_test(nValue);
+ }
+
+ void valueOf_float_test_006()
+ {
+ float nValue = 3.5025255f;
+ valueOf_float_test(nValue);
+ }
+
+ void valueOf_float_test_007()
+ {
+ float nValue = 3.0039062f;
+ valueOf_float_test(nValue);
+ }
+
+private:
+
+ void valueOf_double_test_impl(double _nValue)
+ {
+ OString sValue;
+ sValue = OString::valueOf( _nValue );
+ printf("nDouble := %.20f sValue := %s\n", _nValue, sValue.getStr());
+
+ double nValueATOF = atof( sValue.getStr() );
+
+ bool bEqualResult = is_double_equal(_nValue, nValueATOF);
+ CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
+ }
+
+ void valueOf_double_test(double _nValue)
+ {
+ valueOf_double_test_impl(_nValue);
+
+ // test also the negative part.
+ double nNegativeValue = -_nValue;
+ valueOf_double_test_impl(nNegativeValue);
+ }
+public:
+
+ // valueOf double
+ void valueOf_double_test_001()
+ {
+ double nValue = 3.0;
+ valueOf_double_test(nValue);
+ }
+ void valueOf_double_test_002()
+ {
+ double nValue = 3.5;
+ valueOf_double_test(nValue);
+ }
+ void valueOf_double_test_003()
+ {
+ double nValue = 3.0625;
+ valueOf_double_test(nValue);
+ }
+ void valueOf_double_test_004()
+ {
+ double nValue = 3.1415926535;
+ valueOf_double_test(nValue);
+ }
+ void valueOf_double_test_005()
+ {
+ double nValue = 3.141592653589793;
+ valueOf_double_test(nValue);
+ }
+ void valueOf_double_test_006()
+ {
+ double nValue = 3.1415926535897932;
+ valueOf_double_test(nValue);
+ }
+ void valueOf_double_test_007()
+ {
+ double nValue = 3.14159265358979323;
+ valueOf_double_test(nValue);
+ }
+ void valueOf_double_test_008()
+ {
+ double nValue = 3.141592653589793238462643;
+ valueOf_double_test(nValue);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(valueOf);
+ CPPUNIT_TEST(valueOf_float_test_001);
+ CPPUNIT_TEST(valueOf_float_test_002);
+ CPPUNIT_TEST(valueOf_float_test_003);
+ CPPUNIT_TEST(valueOf_float_test_004);
+ CPPUNIT_TEST(valueOf_float_test_005);
+ CPPUNIT_TEST(valueOf_float_test_006);
+ CPPUNIT_TEST(valueOf_float_test_007);
+
+ CPPUNIT_TEST(valueOf_double_test_001);
+ CPPUNIT_TEST(valueOf_double_test_002);
+ CPPUNIT_TEST(valueOf_double_test_003);
+ CPPUNIT_TEST(valueOf_double_test_004);
+ CPPUNIT_TEST(valueOf_double_test_005);
+ CPPUNIT_TEST(valueOf_double_test_006);
+ CPPUNIT_TEST(valueOf_double_test_007);
+ CPPUNIT_TEST(valueOf_double_test_008);
+ CPPUNIT_TEST_SUITE_END();
+}; // class valueOf
+
+// - toDouble (tests)
+
+class toDouble : public CppUnit::TestFixture
+{
+
+public:
+
+ toDouble()
+ {
+ // testPrecision a;
+ }
+
+ void toDouble_test_impl(OString const& _sValue)
+ {
+ double nValueATOF = atof( _sValue.getStr() );
+
+ // OUString suValue = OUString::createFromAscii( _sValue.getStr() );
+ double nValueToDouble = _sValue.toDouble();
+
+ bool bEqualResult = is_double_equal(nValueToDouble, nValueATOF);
+ CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
+ }
+
+ void toDouble_test(OString const& _sValue)
+ {
+ toDouble_test_impl(_sValue);
+
+ // test also the negative part.
+ OString sNegativValue("-");
+ sNegativValue += _sValue;
+ toDouble_test_impl(sNegativValue);
+ }
+
+ // insert your test code here.
+ void toDouble_selftest()
+ {
+ printf("Start selftest:\n");
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.01) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.0001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.00001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.000001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000000001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000000001) == false);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000000001) == false);
+ // we check til 14 values after comma
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000000000001) == true);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000000000001) == true);
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000000000001) == true);
+ printf("Selftest done.\n");
+ }
+
+ void toDouble_test_3()
+ {
+ OString sValue("3");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_3_5()
+ {
+ OString sValue("3.5");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_3_0625()
+ {
+ OString sValue("3.0625");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_pi()
+ {
+ // value from http://www.angio.net/pi/digits/50.txt
+ OString sValue("3.141592653589793238462643383279502884197169399375");
+ toDouble_test(sValue);
+ }
+
+ void toDouble_test_1()
+ {
+ OString sValue("1");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_10()
+ {
+ OString sValue("10");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_100()
+ {
+ OString sValue("100");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_1000()
+ {
+ OString sValue("1000");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_10000()
+ {
+ OString sValue("10000");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_1e99()
+ {
+ OString sValue("1e99");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_1e_n99()
+ {
+ OString sValue("1e-99");
+ toDouble_test(sValue);
+ }
+ void toDouble_test_1e308()
+ {
+ OString sValue("1e308");
+ toDouble_test(sValue);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toDouble);
+ CPPUNIT_TEST(toDouble_selftest);
+
+ CPPUNIT_TEST(toDouble_test_3);
+ CPPUNIT_TEST(toDouble_test_3_5);
+ CPPUNIT_TEST(toDouble_test_3_0625);
+ CPPUNIT_TEST(toDouble_test_pi);
+ CPPUNIT_TEST(toDouble_test_1);
+ CPPUNIT_TEST(toDouble_test_10);
+ CPPUNIT_TEST(toDouble_test_100);
+ CPPUNIT_TEST(toDouble_test_1000);
+ CPPUNIT_TEST(toDouble_test_10000);
+ CPPUNIT_TEST(toDouble_test_1e99);
+ CPPUNIT_TEST(toDouble_test_1e_n99);
+ CPPUNIT_TEST(toDouble_test_1e308);
+ CPPUNIT_TEST_SUITE_END();
+}; // class toDouble
+
+// - getToken (tests)
+
+class getToken : public CppUnit::TestFixture
+{
+
+public:
+ void getToken_000()
+ {
+ OString sTokenStr;
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OString sToken = sTokenStr.getToken( 0, ';', nIndex );
+ }
+ while ( nIndex >= 0 );
+ // printf("Index %d\n", nIndex);
+ // should not GPF
+ }
+
+ void getToken_001()
+ {
+ OString sTokenStr = "a;b";
+
+ sal_Int32 nIndex = 0;
+
+ OString sToken = sTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be a 'a'", sToken.equals("a") == sal_True);
+
+ /* OString */ sToken = sTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be a 'b'", sToken.equals("b") == sal_True);
+ CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
+ }
+
+ void getToken_002()
+ {
+ OString sTokenStr = "a;b.c";
+
+ sal_Int32 nIndex = 0;
+
+ OString sToken = sTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be a 'a'", sToken.equals("a") == sal_True);
+
+ /* OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be a 'b'", sToken.equals("b") == sal_True);
+
+ /* OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be a 'c'", sToken.equals("c") == sal_True);
+ CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
+ }
+
+ void getToken_003()
+ {
+ OString sTokenStr = "a;;b";
+
+ sal_Int32 nIndex = 0;
+
+ OString sToken = sTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be a 'a'", sToken.equals("a") == sal_True);
+
+ /* OString */ sToken = sTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be empty", sToken.isEmpty());
+
+ /* OString */ sToken = sTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be a 'b'", sToken.equals("b") == sal_True);
+ CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
+ }
+
+ void getToken_004()
+ {
+ OString sTokenStr = "longer.then.ever.";
+
+ sal_Int32 nIndex = 0;
+
+ OString sToken = sTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be 'longer'", sToken.equals("longer") == sal_True);
+
+ /* OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be 'then'", sToken.equals("then") == sal_True);
+
+ /* OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be 'ever'", sToken.equals("ever") == sal_True);
+
+ /* OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be empty", sToken.isEmpty());
+
+ CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
+ }
+
+ CPPUNIT_TEST_SUITE(getToken);
+ CPPUNIT_TEST(getToken_000);
+ CPPUNIT_TEST(getToken_001);
+ CPPUNIT_TEST(getToken_002);
+ CPPUNIT_TEST(getToken_003);
+ CPPUNIT_TEST(getToken_004);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getToken
+
+// testing the method replaceAt( sal_Int32 index, sal_Int32 count,
+// const OString& newStr )
+
+// Developer note: Mindy Liu, 2004-04-23
+// stolen from sal/qa/rtl_strings/rtl_OString.cxx
+
+class replaceAt : public CppUnit::TestFixture
+{
+
+public:
+ sal_Bool check_replaceAt( const OString* expVal, const OString* input,
+ const OString* newStr, sal_Int32 index, sal_Int32 count)
+ {
+ OString aStr1;
+ aStr1= input->replaceAt( index, count, *newStr );
+
+ printf("the result OString is %s#\n", aStr1.getStr() );
+
+ sal_Bool bRes = ( expVal->compareTo(aStr1) == 0 );
+ return bRes;
+ }
+
+ void replaceAt_001()
+ {
+ sal_Bool bRes = check_replaceAt(new OString("Java@Sun"),
+ new OString("Sun java"), new OString("Java@Sun"), 0, 8 );
+ CPPUNIT_ASSERT_MESSAGE("string differs, replace whole string", bRes == sal_True);
+ }
+
+ void replaceAt_002()
+ {
+ sal_Bool bRes = check_replaceAt(new OString("Sun Java desktop system"),
+ new OString("Sun "), new OString("Java desktop system"), 10, 8 );
+ CPPUNIT_ASSERT_MESSAGE("index > length of input string", bRes == sal_True);
+ }
+
+ void replaceAt_003()
+ {
+ sal_Bool bRes = check_replaceAt(new OString("SuJava desktop system"),
+ new OString("Sun "), new OString("Java desktop system"), 2, 64 );
+ CPPUNIT_ASSERT_MESSAGE("larger count", bRes == sal_True);
+ }
+
+ void replaceAt_004()
+ {
+
+ sal_Bool bRes = check_replaceAt(new OString("Java desktop system"),
+ new OString("Sun "), new OString("Java desktop system"), -4, 8 );
+ CPPUNIT_ASSERT_MESSAGE("navigate index", bRes == sal_True);
+ }
+ void replaceAt_005()
+ {
+
+ sal_Bool bRes = check_replaceAt(new OString("Sun Jesktop System"),
+ new OString("Sun Java Desktop System"), new OString(""), 5, 5 );
+ CPPUNIT_ASSERT_MESSAGE("replace with null string", bRes == sal_True);
+ }
+
+ CPPUNIT_TEST_SUITE(replaceAt);
+ CPPUNIT_TEST(replaceAt_001);
+ CPPUNIT_TEST(replaceAt_002);
+ CPPUNIT_TEST(replaceAt_003);
+ CPPUNIT_TEST(replaceAt_004);
+ CPPUNIT_TEST(replaceAt_005);
+ CPPUNIT_TEST_SUITE_END();
+}; // class replaceAt
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OString::valueOf);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OString::toDouble);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OString::getToken);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OString::replaceAt);
+
+} // namespace rtl_OString
+
+// this macro creates an empty function, which will called by the RegisterAllFunctions()
+// to let the user the possibility to also register some functions by hand.
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/ostring/rtl_str.cxx b/sal/qa/rtl/ostring/rtl_str.cxx
new file mode 100644
index 000000000..f7af22008
--- /dev/null
+++ b/sal/qa/rtl/ostring/rtl_str.cxx
@@ -0,0 +1,724 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/string.hxx>
+#include <cstring>
+
+namespace rtl_str
+{
+
+ class compare : public CppUnit::TestFixture
+ {
+ void compare_001()
+ {
+ OString aStr1 = "";
+ OString aStr2 = "";
+
+ sal_Int32 nValue = rtl_str_compare( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002()
+ {
+ OString aStr1 = "Line must be equal.";
+ OString aStr2 = "Line must be equal.";
+
+ sal_Int32 nValue = rtl_str_compare( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_003()
+ {
+ OString aStr1 = "Line must differ.";
+ OString aStr2 = "Line foo bar, ok, differ.";
+
+ sal_Int32 nValue = rtl_str_compare( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(compare);
+ CPPUNIT_TEST(compare_001);
+ CPPUNIT_TEST(compare_002);
+ CPPUNIT_TEST(compare_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compare
+
+ class compareIgnoreAsciiCase : public CppUnit::TestFixture
+ {
+ void compare_001()
+ {
+ OString aStr1 = "";
+ OString aStr2 = "";
+
+ sal_Int32 nValue = rtl_str_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002()
+ {
+ OString aStr1 = "Line must be equal.";
+ OString aStr2 = "Line must be equal.";
+
+ sal_Int32 nValue = rtl_str_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002_1()
+ {
+ OString aStr1 = "Line must be equal.";
+ OString aStr2 = "LINE MUST BE EQUAL.";
+
+ sal_Int32 nValue = rtl_str_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal (if case insensitive).", sal_Int32(0), nValue);
+ }
+
+ void compare_003()
+ {
+ OString aStr1 = "Line must differ.";
+ OString aStr2 = "Line foo bar, ok, differ.";
+
+ sal_Int32 nValue = rtl_str_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(compareIgnoreAsciiCase);
+ CPPUNIT_TEST(compare_001);
+ CPPUNIT_TEST(compare_002);
+ CPPUNIT_TEST(compare_002_1);
+ CPPUNIT_TEST(compare_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compareIgnoreAsciiCase
+
+ class shortenedCompareIgnoreAsciiCase_WithLength : public CppUnit::TestFixture
+ {
+ void compare_000()
+ {
+ rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( nullptr, 0, nullptr, 0, 0);
+ }
+
+ void compare_000_1()
+ {
+ OString aStr1 = "Line must be equal.";
+ rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), nullptr, 0, 1);
+ }
+ void compare_001()
+ {
+ OString aStr1 = "";
+ OString aStr2 = "";
+
+ sal_Int32 nValue = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), aStr2.getStr(), aStr2.getLength(), aStr1.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002()
+ {
+ OString aStr1 = "Line must be equal.";
+ OString aStr2 = "Line must be equal.";
+
+ sal_Int32 nValue = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ aStr1.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002_1()
+ {
+ OString aStr1 = "Line must be equal.";
+ OString aStr2 = "LINE MUST BE EQUAL.";
+
+ sal_Int32 nValue = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ aStr1.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal (if case insensitive).", sal_Int32(0), nValue);
+ }
+
+ void compare_003()
+ {
+ OString aStr1 = "Line must differ.";
+ OString aStr2 = "Line foo bar, ok, differ.";
+
+ sal_Int32 nValue = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ 5);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal first 5 characters.", sal_Int32(0), nValue);
+ }
+
+ void compare_004()
+ {
+ OString aStr1 = "Line must differ.";
+ OString aStr2 = "Line foo bar, ok, differ.";
+
+ sal_Int32 nValue = rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ aStr1.getLength());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(shortenedCompareIgnoreAsciiCase_WithLength);
+ CPPUNIT_TEST(compare_000);
+ CPPUNIT_TEST(compare_000_1);
+ CPPUNIT_TEST(compare_001);
+ CPPUNIT_TEST(compare_002);
+ CPPUNIT_TEST(compare_002_1);
+ CPPUNIT_TEST(compare_003);
+ CPPUNIT_TEST(compare_004);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compare
+
+ class hashCode : public CppUnit::TestFixture
+ {
+ void hashCode_001()
+ {
+ OString aStr1 = "Line for a hashCode.";
+ sal_Int32 nHashCode = rtl_str_hashCode( aStr1.getStr() );
+ printf("hashcode: %" SAL_PRIdINT32 "\n", nHashCode);
+ // CPPUNIT_ASSERT_MESSAGE("failed.", nValue == 0);
+ }
+
+ void hashCode_002()
+ {
+ OString aStr1 = "Line for a hashCode.";
+ sal_Int32 nHashCode1 = rtl_str_hashCode( aStr1.getStr() );
+
+ OString aStr2 = "Line for a hashCode.";
+ sal_Int32 nHashCode2 = rtl_str_hashCode( aStr2.getStr() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("hashcodes must be equal.", nHashCode1, nHashCode2 );
+ }
+
+ void hashCode_003()
+ {
+ OString aStr1 = "Line for a hashCode.";
+ sal_Int32 nHashCode1 = rtl_str_hashCode( aStr1.getStr() );
+
+ OString aStr2 = "Line for another hashcode.";
+ sal_Int32 nHashCode2 = rtl_str_hashCode( aStr2.getStr() );
+
+ CPPUNIT_ASSERT_MESSAGE("hashcodes must differ.", nHashCode1 != nHashCode2 );
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(hashCode);
+ CPPUNIT_TEST(hashCode_001);
+ CPPUNIT_TEST(hashCode_002);
+ CPPUNIT_TEST(hashCode_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compare
+
+ class indexOfChar : public CppUnit::TestFixture
+ {
+ void indexOfChar_000()
+ {
+ sal_Int32 nIndex = rtl_str_indexOfChar("", 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Trailing zero character is not part of the string",
+ sal_Int32(-1), nIndex);
+ }
+
+ void indexOfChar_001()
+ {
+ OString aStr1 = "Line for an indexOfChar.";
+
+ sal_Int32 nIndex = rtl_str_indexOfChar( aStr1.getStr(), 'L' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(0), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_indexOfChar( aStr1.getStr(), 'i' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(1), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_indexOfChar( aStr1.getStr(), 'n' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(2), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_indexOfChar( aStr1.getStr(), 'e' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(3), nIndex);
+ }
+
+ void indexOfChar_002()
+ {
+ OString aStr1 = "Line for an indexOfChar.";
+ sal_Int32 nIndex = rtl_str_indexOfChar( aStr1.getStr(), 'y' );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(indexOfChar);
+ CPPUNIT_TEST(indexOfChar_000);
+ CPPUNIT_TEST(indexOfChar_001);
+ CPPUNIT_TEST(indexOfChar_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compare
+
+ class lastIndexOfChar : public CppUnit::TestFixture
+ {
+ void lastIndexOfChar_000()
+ {
+ sal_Int32 nIndex = rtl_str_lastIndexOfChar("", 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Trailing zero character is not part of the string",
+ sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfChar_001()
+ {
+ OString aStr1 = "Line for a lastIndexOfChar.";
+
+ sal_Int32 nIndex = rtl_str_lastIndexOfChar( aStr1.getStr(), 'C' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(22), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_lastIndexOfChar( aStr1.getStr(), 'h' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(23), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_lastIndexOfChar( aStr1.getStr(), 'a' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(24), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_lastIndexOfChar( aStr1.getStr(), 'r' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(25), nIndex);
+ }
+
+ void lastIndexOfChar_002()
+ {
+ OString aStr1 = "Line for a lastIndexOfChar.";
+ sal_Int32 nIndex = rtl_str_lastIndexOfChar( aStr1.getStr(), 'y' );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(lastIndexOfChar);
+ CPPUNIT_TEST(lastIndexOfChar_000);
+ CPPUNIT_TEST(lastIndexOfChar_001);
+ CPPUNIT_TEST(lastIndexOfChar_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class lastIndexOfChar
+
+ class indexOfStr : public CppUnit::TestFixture
+ {
+ void indexOfStr_000()
+ {
+ OString aStr1("Line for an indexOfStr.");
+ sal_Int32 nIndex = rtl_str_indexOfStr( aStr1.getStr(), "" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("an empty substring is always not findable",
+ sal_Int32(-1), nIndex);
+ }
+
+ void indexOfStr_001()
+ {
+ OString aStr1 = "Line for an indexOfStr.";
+
+ sal_Int32 nIndex = rtl_str_indexOfStr( aStr1.getStr(), "Line" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(0), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_indexOfStr( aStr1.getStr(), "for" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(5), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_indexOfStr( aStr1.getStr(), "a" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(9), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_str_indexOfStr( aStr1.getStr(), "an index" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(9), nIndex);
+ }
+
+ void indexOfStr_002()
+ {
+ OString aStr1 = "Line for an indexOfStr.";
+ sal_Int32 nIndex = rtl_str_indexOfStr( aStr1.getStr(), "not exist" );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(indexOfStr);
+ CPPUNIT_TEST(indexOfStr_000);
+ CPPUNIT_TEST(indexOfStr_001);
+ CPPUNIT_TEST(indexOfStr_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compare
+
+ class lastIndexOfStr : public CppUnit::TestFixture
+ {
+ void lastIndexOfStr_000()
+ {
+ OString aStr1("Line for a lastIndexOfStr.");
+ sal_Int32 nIndex = rtl_str_lastIndexOfStr( aStr1.getStr(), "" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("an empty substring is always not findable",
+ sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfStr_001()
+ {
+ OString aStr1 = "Line for a lastIndexOfStr.";
+ OString aSearchStr = "Index";
+
+ sal_Int32 nIndex = rtl_str_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(15), nIndex);
+
+ /* OString */ aSearchStr = "Line";
+ /* sal_Int32 */ nIndex = rtl_str_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(0), nIndex);
+
+ /* OString */ aSearchStr = "";
+ /* sal_Int32 */ nIndex = rtl_str_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfStr_002()
+ {
+ OString aStr1 = "Line for a lastIndexOfStr.";
+ OString aSearchStr = "foo";
+ sal_Int32 nIndex = rtl_str_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfStr_003()
+ {
+ OString aStr1 = "Line for a lastIndexOfStr.";
+ OString aSearchStr = "O";
+ sal_Int32 nIndex = rtl_str_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(20), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(lastIndexOfStr);
+ CPPUNIT_TEST(lastIndexOfStr_000);
+ CPPUNIT_TEST(lastIndexOfStr_001);
+ CPPUNIT_TEST(lastIndexOfStr_002);
+ CPPUNIT_TEST(lastIndexOfStr_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class lastIndexOfStr
+
+ class replaceChar : public CppUnit::TestFixture
+ {
+ void replaceChar_001()
+ {
+ OString aStr1 = "replace char.";
+ OString aShouldStr1 = "ruplacu char.";
+
+ char* pStr = static_cast<char*>(malloc(aStr1.getLength() + 1));
+ CPPUNIT_ASSERT_MESSAGE("can't get memory for test", pStr != nullptr);
+ strcpy(pStr, aStr1.getStr());
+
+ rtl_str_replaceChar( pStr, 'e', 'u' );
+
+ CPPUNIT_ASSERT_MESSAGE("replace failed", aShouldStr1.equals(OString(pStr)));
+ free(pStr);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(replaceChar);
+ CPPUNIT_TEST(replaceChar_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class replaceChar_WithLength : public CppUnit::TestFixture
+ {
+ void replaceChar_WithLength_000()
+ {
+ rtl_str_replaceChar_WithLength( nullptr, 0, 0, 0 );
+ }
+
+ void replaceChar_WithLength_001()
+ {
+ OString aStr1 = "replace char.";
+ OString aShouldStr1 = "ruplace char.";
+
+ char* pStr = static_cast<char*>(malloc(aStr1.getLength() + 1));
+ CPPUNIT_ASSERT_MESSAGE("can't get memory for test", pStr != nullptr);
+ strcpy(pStr, aStr1.getStr());
+
+ rtl_str_replaceChar_WithLength( pStr, 6, 'e', 'u' );
+
+ CPPUNIT_ASSERT_MESSAGE("replace failed", aShouldStr1.equals(OString(pStr)));
+ free(pStr);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(replaceChar_WithLength);
+ CPPUNIT_TEST(replaceChar_WithLength_000);
+ CPPUNIT_TEST(replaceChar_WithLength_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiLowerCase : public CppUnit::TestFixture
+ {
+ void toAsciiLowerCase_001()
+ {
+ OString aStr1 = "CHANGE THIS TO ASCII LOWER CASE.";
+ OString aShouldStr1 = "change this to ascii lower case.";
+
+ char* pStr = static_cast<char*>(malloc(aStr1.getLength() + 1));
+ CPPUNIT_ASSERT_MESSAGE("can't get memory for test", pStr != nullptr);
+ strcpy(pStr, aStr1.getStr());
+
+ rtl_str_toAsciiLowerCase( pStr );
+
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(OString(pStr)));
+ free(pStr);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiLowerCase);
+ CPPUNIT_TEST(toAsciiLowerCase_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiLowerCase_WithLength : public CppUnit::TestFixture
+ {
+ void toAsciiLowerCase_WithLength_000()
+ {
+ rtl_str_toAsciiLowerCase_WithLength( nullptr, 0 );
+ }
+
+ void toAsciiLowerCase_WithLength_001()
+ {
+ OString aStr1 = "CHANGE THIS TO ASCII LOWER CASE.";
+ OString aShouldStr1 = "change thiS TO ASCII LOWER CASE.";
+
+ char* pStr = static_cast<char*>(malloc(aStr1.getLength() + 1));
+ CPPUNIT_ASSERT_MESSAGE("can't get memory for test", pStr != nullptr);
+ strcpy(pStr, aStr1.getStr());
+
+ rtl_str_toAsciiLowerCase_WithLength( pStr, 10 );
+
+ printf("Lowercase with length: '%s'\n", pStr);
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(OString(pStr)));
+ free(pStr);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiLowerCase_WithLength);
+ CPPUNIT_TEST(toAsciiLowerCase_WithLength_000);
+ CPPUNIT_TEST(toAsciiLowerCase_WithLength_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiUpperCase : public CppUnit::TestFixture
+ {
+ void toAsciiUpperCase_001()
+ {
+ OString aStr1 = "change this to ascii upper case.";
+ OString aShouldStr1 = "CHANGE THIS TO ASCII UPPER CASE.";
+
+ char* pStr = static_cast<char*>(malloc(aStr1.getLength() + 1));
+ CPPUNIT_ASSERT_MESSAGE("can't get memory for test", pStr != nullptr);
+ strcpy(pStr, aStr1.getStr());
+
+ rtl_str_toAsciiUpperCase( pStr );
+
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(OString(pStr)));
+ free(pStr);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiUpperCase);
+ CPPUNIT_TEST(toAsciiUpperCase_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiUpperCase_WithLength : public CppUnit::TestFixture
+ {
+ void toAsciiUpperCase_WithLength_000()
+ {
+ rtl_str_toAsciiUpperCase_WithLength( nullptr, 0 );
+ }
+
+ void toAsciiUpperCase_WithLength_001()
+ {
+ OString aStr1 = "change this to ascii lower case.";
+ OString aShouldStr1 = "CHANGE THIs to ascii lower case.";
+
+ char* pStr = static_cast<char*>(malloc(aStr1.getLength() + 1));
+ CPPUNIT_ASSERT_MESSAGE("can't get memory for test", pStr != nullptr);
+
+ strcpy(pStr, aStr1.getStr());
+ rtl_str_toAsciiUpperCase_WithLength( pStr, 10 );
+
+ printf("Uppercase with length: '%s'\n", aStr1.getStr());
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(OString(pStr)));
+ free(pStr);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiUpperCase_WithLength);
+ CPPUNIT_TEST(toAsciiUpperCase_WithLength_000);
+ CPPUNIT_TEST(toAsciiUpperCase_WithLength_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class trim_WithLength : public CppUnit::TestFixture
+ {
+ void trim_WithLength_000()
+ {
+ rtl_str_trim_WithLength(nullptr, 0);
+ // should not GPF
+ }
+
+ void trim_WithLength_000_1()
+ {
+ char pStr[] = { " trim this" };
+ rtl_str_trim_WithLength( pStr, 0 );
+ }
+
+ void trim_WithLength_001()
+ {
+ char pStr[] = { " trim this" };
+ rtl_str_trim_WithLength( pStr, 2 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should be empty", size_t(0), strlen(pStr));
+ }
+
+ void trim_WithLength_002()
+ {
+ char pStr[] = { "trim this" };
+ rtl_str_trim_WithLength( pStr, 5 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim'", size_t(4), strlen(pStr));
+ }
+
+ void trim_WithLength_003()
+ {
+ char pStr[] = {" trim this"};
+ rtl_str_trim_WithLength( pStr, 11 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim'", size_t(4), strlen(pStr));
+ }
+
+ void trim_WithLength_004()
+ {
+ char pStr[] = { "\r\n\t \n\r trim \n this" };
+ rtl_str_trim_WithLength( pStr, 17 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim'", size_t(4), strlen(pStr));
+ }
+
+ void trim_WithLength_005()
+ {
+ char pStr[] = { "\r\n\t \n\r trim \t this \n\r\t\t " };
+ rtl_str_trim_WithLength( pStr, strlen(pStr) );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim \t this'", size_t(11), strlen(pStr));
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(trim_WithLength);
+ CPPUNIT_TEST(trim_WithLength_000);
+ CPPUNIT_TEST(trim_WithLength_000_1);
+ CPPUNIT_TEST(trim_WithLength_001);
+ CPPUNIT_TEST(trim_WithLength_002);
+ CPPUNIT_TEST(trim_WithLength_003);
+ CPPUNIT_TEST(trim_WithLength_004);
+ CPPUNIT_TEST(trim_WithLength_005);
+ CPPUNIT_TEST_SUITE_END();
+ };
+
+ class valueOfChar : public CppUnit::TestFixture
+ {
+ void valueOfChar_001()
+ {
+ char pStr[RTL_STR_MAX_VALUEOFCHAR];
+ rtl_str_valueOfChar(pStr, 'A');
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'A'", 'A', pStr[0]);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(valueOfChar);
+ CPPUNIT_TEST(valueOfChar_001);
+ CPPUNIT_TEST_SUITE_END();
+ };
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::compare);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::compareIgnoreAsciiCase);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::shortenedCompareIgnoreAsciiCase_WithLength);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::hashCode);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::indexOfChar);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::lastIndexOfChar);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::indexOfStr);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::lastIndexOfStr);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::replaceChar);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::replaceChar_WithLength);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::toAsciiLowerCase);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::toAsciiLowerCase_WithLength);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::toAsciiUpperCase);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::toAsciiUpperCase_WithLength);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::trim_WithLength);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_str::valueOfChar);
+
+} // namespace rtl_str
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/ostring/rtl_str.xsce b/sal/qa/rtl/ostring/rtl_str.xsce
new file mode 100644
index 000000000..cd12e72f7
--- /dev/null
+++ b/sal/qa/rtl/ostring/rtl_str.xsce
@@ -0,0 +1,43 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+# signaled with SIGNAL 11
+rtl_str.compare.compare_000
+rtl_str.compare.compare_000_1
+
+rtl_str.compareIgnoreAsciiCase.compare_000
+rtl_str.compareIgnoreAsciiCase.compare_000_1
+
+rtl_str.hashCode.hashCode_000
+
+rtl_str.indexOfChar.indexOfChar_000
+
+rtl_str.lastIndexOfChar.lastIndexOfChar_000
+
+rtl_str.indexOfStr.indexOfStr_000
+
+rtl_str.lastIndexOfStr.lastIndexOfStr_000
+
+rtl_str.replaceChar.replaceChar_000
+
+rtl_str.replaceChar_WithLength.replaceChar_WithLength_000_1
+
+rtl_str.toAsciiLowerCase.toAsciiLowerCase_000
+
+rtl_str.toAsciiUpperCase.toAsciiUpperCase_000
+
+rtl_str.valueOfChar.valueOfChar_000
diff --git a/sal/qa/rtl/ostring/rtl_string.cxx b/sal/qa/rtl/ostring/rtl_string.cxx
new file mode 100644
index 000000000..71c709519
--- /dev/null
+++ b/sal/qa/rtl/ostring/rtl_string.cxx
@@ -0,0 +1,169 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/ustring.hxx>
+#include <cstring>
+
+namespace rtl_string
+{
+
+ class getLength : public CppUnit::TestFixture
+ {
+ public:
+
+ void getLength_000()
+ {
+ rtl_string_getLength( NULL );
+ // should not GPF
+ }
+
+ void getLength_001()
+ {
+ OString aStr("Test Length.");
+ sal_Int32 nValue = rtl_string_getLength( aStr.pData );
+
+ CPPUNIT_ASSERT_MESSAGE("Length must equal getLength()", aStr.getLength() == nValue);
+ CPPUNIT_ASSERT_MESSAGE(
+ "Length must equal strlen()",
+ nValue >= 0
+ && (strlen(aStr.getStr())
+ == sal::static_int_cast< sal_uInt32 >(nValue)));
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(getLength);
+ CPPUNIT_TEST(getLength_000);
+ CPPUNIT_TEST(getLength_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class getLength
+
+ class newFromString : public CppUnit::TestFixture
+ {
+ public:
+
+ // void newFromString_000()
+ // {
+ // sal_Int32 nValue = rtl_string_newFromString( NULL, NULL );
+ // // should not GPF
+ // }
+
+ void newFromString_001()
+ {
+ OString aStr("Test Length.");
+ rtl_String *pStr = NULL;
+
+ rtl_string_newFromString( &pStr, aStr.pData );
+
+ OString aNewStr(pStr);
+ CPPUNIT_ASSERT_MESSAGE("Strings must be equal", aStr.equals(aNewStr) == sal_True);
+
+ rtl_string_release(pStr);
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(newFromString);
+ // CPPUNIT_TEST(newFromString_000);
+ CPPUNIT_TEST(newFromString_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class newFromString
+
+ class convertUStringToString : public CppUnit::TestFixture
+ {
+ public:
+
+ // void newFromString_000()
+ // {
+ // sal_Int32 nValue = rtl_string_newFromString( NULL, NULL );
+ // // should not GPF
+ // }
+
+ void convertUStringToString_001()
+ {
+ OUString suString("Hello");
+ OString sString;
+ sal_Bool bRet = rtl_convertUStringToString(&sString.pData, suString.getStr(), suString.getLength(), RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ CPPUNIT_ASSERT_MESSAGE("Strings must be equal", bRet == sal_True && sString.equals(OString("Hello")) == sal_True);
+ }
+
+ void convertUStringToString_002()
+ {
+ OString sStr("H\xE4llo");
+ OUString suString = OStringToOUString(sStr, RTL_TEXTENCODING_ISO_8859_15);
+
+ OString sString;
+ sal_Bool bRet = rtl_convertUStringToString(&sString.pData, suString.getStr(), suString.getLength(), RTL_TEXTENCODING_ISO_8859_15, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ CPPUNIT_ASSERT_MESSAGE("Strings must be equal", bRet == sal_True && sString.equals(OString("H\xE4llo")) == sal_True);
+ }
+
+ void convertUStringToString_003()
+ {
+ OString sStr("H\xC3\xA4llo");
+ OUString suString = OStringToOUString(sStr, RTL_TEXTENCODING_UTF8);
+
+ OString sString;
+ sal_Bool bRet = rtl_convertUStringToString(&sString.pData, suString.getStr(), suString.getLength(), RTL_TEXTENCODING_ISO_8859_15, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ CPPUNIT_ASSERT_MESSAGE("Strings must be equal", bRet == sal_True && sString.equals(OString("H\xE4llo")) == sal_True);
+ }
+
+ void convertUStringToString_004()
+ {
+ OString sStr("Tsch\xFC\xDF");
+ OUString suString = OStringToOUString(sStr, RTL_TEXTENCODING_ISO_8859_15);
+ OString sString;
+
+ sal_Bool bRet = rtl_convertUStringToString(&sString.pData, suString.getStr(), suString.getLength(), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+ /* sal_Bool */ bRet = rtl_convertUStringToString(&sString.pData, suString.getStr(), suString.getLength(), RTL_TEXTENCODING_ISO_8859_15, OUSTRING_TO_OSTRING_CVTFLAGS);
+ CPPUNIT_ASSERT_MESSAGE("Strings must be equal", bRet == sal_True && sString.equals(OString("Tsch\xFC\xDF")) == sal_True);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(convertUStringToString);
+ CPPUNIT_TEST(convertUStringToString_001);
+ CPPUNIT_TEST(convertUStringToString_002);
+ CPPUNIT_TEST(convertUStringToString_003);
+ CPPUNIT_TEST(convertUStringToString_004);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class convertUStringToString
+
+} // namespace rtl_string
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_string::getLength);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_string::newFromString);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_string::convertUStringToString);
+
+// this macro creates an empty function, which will called by the RegisterAllFunctions()
+// to let the user the possibility to also register some functions by hand.
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/ostring/rtl_string.xsce b/sal/qa/rtl/ostring/rtl_string.xsce
new file mode 100644
index 000000000..7c8227e49
--- /dev/null
+++ b/sal/qa/rtl/ostring/rtl_string.xsce
@@ -0,0 +1,18 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+rtl_string.getLength.getLength_000
diff --git a/sal/qa/rtl/oustring/joblist.txt b/sal/qa/rtl/oustring/joblist.txt
new file mode 100644
index 000000000..c309c670d
--- /dev/null
+++ b/sal/qa/rtl/oustring/joblist.txt
@@ -0,0 +1,27 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+# JobFile for rtl_OUString
+# header source sal/inc/rtl/ustring.hxx
+
+rtl_OUString.valueOf.valueOf_double_001
+rtl_OUString.valueOf.valueOf_double_002
+rtl_OUString.valueOf.valueOf_double_003
+rtl_OUString.valueOf.valueOf_double_004
+rtl_OUString.valueOf.valueOf_double_005
+rtl_OUString.valueOf.valueOf_double_006
+rtl_OUString.valueOf.valueOf_double_007
diff --git a/sal/qa/rtl/oustring/rtl_OUString2.cxx b/sal/qa/rtl/oustring/rtl_OUString2.cxx
new file mode 100644
index 000000000..22e731fd1
--- /dev/null
+++ b/sal/qa/rtl/oustring/rtl_OUString2.cxx
@@ -0,0 +1,1068 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// autogenerated file with codegen.pl
+
+#include <memory>
+#include <math.h>
+#include <stdio.h>
+
+#include <algorithm>
+#include <limits>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <config_options.h>
+#include <o3tl/cppunittraitshelper.hxx>
+#include <o3tl/safeint.hxx>
+
+#include <stringhelper.hxx>
+#include <valueequal.hxx>
+
+namespace rtl_OUString
+{
+
+namespace {
+
+// Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
+// outside the range of representable values of type 'float'" with Clang prior to
+// <https://github.com/llvm/llvm-project/commit/9e52c43090f8cd980167bbd2719878ae36bcf6b5> "Treat the
+// range of representable values of floating-point types as [-inf, +inf] not as [-max, +max]"
+// (ENABLE_RUNTIME_OPTIMIZATIONS is an approximation for checking whether building is done without
+// -fsanitize=undefined):
+float doubleToFloat(double x) {
+#if !defined __clang__ || __clang_major__ >= 9 || ENABLE_RUNTIME_OPTIMIZATIONS
+ return static_cast<float>(x);
+#else
+ return
+ x < -std::numeric_limits<float>::max()
+ ? -std::numeric_limits<float>::infinity()
+ : x > std::numeric_limits<float>::max()
+ ? std::numeric_limits<float>::infinity()
+ : static_cast<float>(x);
+#endif
+}
+
+}
+
+class number : public CppUnit::TestFixture
+{
+ void number_float_test_impl(float _nValue)
+ {
+ OUString suValue(OUString::number(_nValue));
+ OString sValue;
+ sValue <<= suValue;
+ printf("nFloat := %.9f sValue := %s\n", _nValue, sValue.getStr());
+
+ double nValueATOF = doubleToFloat(atof( sValue.getStr() ));
+
+ bool bEqualResult = is_float_equal(_nValue, nValueATOF);
+ CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
+ }
+
+ void number_float_test(float _nValue)
+ {
+ number_float_test_impl(_nValue);
+
+ // test also the negative part.
+ float nNegativeValue = -_nValue;
+ number_float_test_impl(nNegativeValue);
+ }
+
+public:
+ // insert your test code here.
+ void number_float_test_001()
+ {
+ // this is demonstration code
+ // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1);
+ float nValue = 3.0f;
+ number_float_test(nValue);
+ }
+
+ void number_float_test_002()
+ {
+ float nValue = 3.5f;
+ number_float_test(nValue);
+ }
+
+ void number_float_test_003()
+ {
+ float nValue = 3.0625f;
+ number_float_test(nValue);
+ }
+
+ void number_float_test_004()
+ {
+ float nValue = 3.502525f;
+ number_float_test(nValue);
+ }
+
+ void number_float_test_005()
+ {
+ float nValue = 3.141592f;
+ number_float_test(nValue);
+ }
+
+ void number_float_test_006()
+ {
+ float nValue = 3.5025255f;
+ number_float_test(nValue);
+ }
+
+ void number_float_test_007()
+ {
+ float nValue = 3.0039062f;
+ number_float_test(nValue);
+ }
+
+private:
+
+ void number_double_test_impl(double _nValue)
+ {
+ OUString suValue = OUString::number( _nValue );
+ OString sValue;
+ sValue <<= suValue;
+ printf("nDouble := %.20f sValue := %s\n", _nValue, sValue.getStr());
+
+ double nValueATOF = atof( sValue.getStr() );
+
+ bool bEqualResult = is_double_equal(_nValue, nValueATOF);
+ CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
+ }
+
+ void number_double_test(double _nValue)
+ {
+ number_double_test_impl(_nValue);
+
+ // test also the negative part.
+ double nNegativeValue = -_nValue;
+ number_double_test_impl(nNegativeValue);
+ }
+public:
+
+ // number double
+ void number_double_test_001()
+ {
+ double nValue = 3.0;
+ number_double_test(nValue);
+ }
+ void number_double_test_002()
+ {
+ double nValue = 3.5;
+ number_double_test(nValue);
+ }
+ void number_double_test_003()
+ {
+ double nValue = 3.0625;
+ number_double_test(nValue);
+ }
+ void number_double_test_004()
+ {
+ double nValue = 3.1415926535;
+ number_double_test(nValue);
+ }
+ void number_double_test_005()
+ {
+ double nValue = 3.141592653589793;
+ number_double_test(nValue);
+ }
+ void number_double_test_006()
+ {
+ double nValue = 3.1415926535897932;
+ number_double_test(nValue);
+ }
+ void number_double_test_007()
+ {
+ double nValue = 3.14159265358979323;
+ number_double_test(nValue);
+ }
+ void number_double_test_008()
+ {
+ double nValue = 3.141592653589793238462643;
+ number_double_test(nValue);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(number);
+ CPPUNIT_TEST(number_float_test_001);
+ CPPUNIT_TEST(number_float_test_002);
+ CPPUNIT_TEST(number_float_test_003);
+ CPPUNIT_TEST(number_float_test_004);
+ CPPUNIT_TEST(number_float_test_005);
+ CPPUNIT_TEST(number_float_test_006);
+ CPPUNIT_TEST(number_float_test_007);
+
+ CPPUNIT_TEST(number_double_test_001);
+ CPPUNIT_TEST(number_double_test_002);
+ CPPUNIT_TEST(number_double_test_003);
+ CPPUNIT_TEST(number_double_test_004);
+ CPPUNIT_TEST(number_double_test_005);
+ CPPUNIT_TEST(number_double_test_006);
+ CPPUNIT_TEST(number_double_test_007);
+ CPPUNIT_TEST(number_double_test_008);
+ CPPUNIT_TEST_SUITE_END();
+}; // class number
+
+ class toInt: public CppUnit::TestFixture {
+ public:
+ void test() {
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast< sal_Int32 >(-0x76543210),
+ (OUString("-76543210").
+ toInt32(16)));
+ // @return 0 if this string represents no number or one of too large magnitude
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast< sal_Int32 >(0),
+ (OUString("+FEDCBA98").
+ toInt32(16)));
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast< sal_Int64 >(-SAL_CONST_INT64(0x76543210FEDCBA98)),
+ (OUString(
+ "-76543210FEDCBA98").
+ toInt64(16)));
+ // @return 0 if this string represents no number or one of too large magnitude
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast< sal_Int64 >(SAL_CONST_INT64(0)),
+ (OUString(
+ "+FEDCBA9876543210").
+ toInt64(16)));
+ }
+
+ CPPUNIT_TEST_SUITE(toInt);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+ };
+
+ // - toDouble (tests)
+ class toDouble : public CppUnit::TestFixture
+ {
+ public:
+ void toDouble_test_impl(OString const& _sValue)
+ {
+ //printf("the original str is %s\n", _sValue.getStr());
+ double nValueATOF = atof( _sValue.getStr() );
+ //printf("original data is %e\n", nValueATOF);
+ OUString suValue = OUString::createFromAscii( _sValue.getStr() );
+ double nValueToDouble = suValue.toDouble();
+ //printf("result data is %e\n", nValueToDouble);
+
+ bool bEqualResult = is_double_equal(nValueToDouble, nValueATOF);
+ CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
+ }
+
+ void toDouble_test(OString const& _sValue)
+ {
+ toDouble_test_impl(_sValue);
+
+ // test also the negative part.
+ OString sNegativValue("-");
+ sNegativValue += _sValue;
+ toDouble_test_impl(sNegativValue);
+ }
+
+ // insert your test code here.
+ void toDouble_selftest()
+ {
+ printf("Start selftest:\n");
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.01));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00000001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000000001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000000001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.00000000001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.000000000001));
+ CPPUNIT_ASSERT (!is_double_equal(1.0, 1.0000000000001));
+ // we check til 15 values after comma
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000000000001));
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000000000001));
+ CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000000000001));
+ printf("Selftest done.\n");
+ }
+
+ void toDouble_test_3()
+ {
+ toDouble_test("3");
+ }
+ void toDouble_test_3_5()
+ {
+ toDouble_test("3.5");
+ }
+ void toDouble_test_3_0625()
+ {
+ toDouble_test("3.0625");
+ }
+ void toDouble_test_pi()
+ {
+ // value from http://www.angio.net/pi/digits/50.txt
+ toDouble_test("3.141592653589793238462643383279502884197169399375");
+ }
+
+ void toDouble_test_1()
+ {
+ toDouble_test("1");
+ }
+ void toDouble_test_10()
+ {
+ toDouble_test("10");
+ }
+ void toDouble_test_100()
+ {
+ toDouble_test("100");
+ }
+ void toDouble_test_1000()
+ {
+ toDouble_test("1000");
+ }
+ void toDouble_test_10000()
+ {
+ toDouble_test("10000");
+ }
+ void toDouble_test_1e99()
+ {
+ toDouble_test("1e99");
+ }
+ void toDouble_test_1e_n99()
+ {
+ toDouble_test("1e-99");
+ }
+ void toDouble_test_1e308()
+ {
+ toDouble_test("1e308");
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toDouble);
+ CPPUNIT_TEST(toDouble_selftest);
+
+ CPPUNIT_TEST(toDouble_test_3);
+ CPPUNIT_TEST(toDouble_test_3_5);
+ CPPUNIT_TEST(toDouble_test_3_0625);
+ CPPUNIT_TEST(toDouble_test_pi);
+ CPPUNIT_TEST(toDouble_test_1);
+ CPPUNIT_TEST(toDouble_test_10);
+ CPPUNIT_TEST(toDouble_test_100);
+ CPPUNIT_TEST(toDouble_test_1000);
+ CPPUNIT_TEST(toDouble_test_10000);
+ CPPUNIT_TEST(toDouble_test_1e99);
+ CPPUNIT_TEST(toDouble_test_1e_n99);
+ CPPUNIT_TEST(toDouble_test_1e308);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class toDouble
+
+ // - toFloat (tests)
+ class toFloat : public CppUnit::TestFixture
+ {
+ public:
+ void toFloat_test_impl(OString const& _sValue)
+ {
+ //printf("the original str is %s\n", _sValue.getStr());
+ float nValueATOF = doubleToFloat(atof( _sValue.getStr() ));
+ //printf("the original str is %.10f\n", nValueATOF);
+ OUString suValue = OUString::createFromAscii( _sValue.getStr() );
+ float nValueToFloat = suValue.toFloat();
+ //printf("the result str is %.10f\n", nValueToFloat);
+
+ bool bEqualResult = is_float_equal(nValueToFloat, nValueATOF);
+ CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult);
+ }
+
+ void toFloat_test(OString const& _sValue)
+ {
+ toFloat_test_impl(_sValue);
+
+ // test also the negative part.
+ OString sNegativValue("-");
+ sNegativValue += _sValue;
+ toFloat_test_impl(sNegativValue);
+ }
+
+ // insert your test code here.
+ void toFloat_selftest()
+ {
+ printf("Start selftest:\n");
+ CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.01f));
+ CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.001f));
+ CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.0001f));
+ CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.00001f));
+ CPPUNIT_ASSERT (!is_float_equal(1.0f, 1.000002f));
+ CPPUNIT_ASSERT (is_float_equal(1.0f, 1.0000001f));
+ CPPUNIT_ASSERT (is_float_equal(1.0f, 1.00000001f));
+ CPPUNIT_ASSERT (is_float_equal(1.0f, 1.000000001f));
+
+ printf("Selftest done.\n");
+ }
+
+ void toFloat_test_3()
+ {
+ toFloat_test("3");
+ }
+ void toFloat_test_3_5()
+ {
+ toFloat_test("3.5");
+ }
+ void toFloat_test_3_0625()
+ {
+ toFloat_test("3.0625");
+ }
+ void toFloat_test_3_0625_e()
+ {
+ toFloat_test("3.0625e-4");
+ }
+ void toFloat_test_pi()
+ {
+ // value from http://www.angio.net/pi/digits/50.txt
+ toFloat_test("3.141592653589793238462643383279502884197169399375");
+ }
+
+ void toFloat_test_1()
+ {
+ toFloat_test("1");
+ }
+ void toFloat_test_10()
+ {
+ toFloat_test("10");
+ }
+ void toFloat_test_100()
+ {
+ toFloat_test("100");
+ }
+ void toFloat_test_1000()
+ {
+ toFloat_test("1000");
+ }
+ void toFloat_test_10000()
+ {
+ toFloat_test("10000");
+ }
+ void toFloat_test_mix()
+ {
+ toFloat_test("456789321455.123456789012");
+ }
+ void toFloat_test_1e99()
+ {
+ toFloat_test("1e99");
+ }
+ void toFloat_test_1e_n99()
+ {
+ toFloat_test("1e-9");
+ }
+ void toFloat_test_1e308()
+ {
+ toFloat_test("1e308");
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toFloat);
+ CPPUNIT_TEST(toFloat_selftest);
+
+ CPPUNIT_TEST(toFloat_test_3);
+ CPPUNIT_TEST(toFloat_test_3_5);
+ CPPUNIT_TEST(toFloat_test_3_0625);
+ CPPUNIT_TEST(toFloat_test_3_0625_e);
+ CPPUNIT_TEST(toFloat_test_pi);
+ CPPUNIT_TEST(toFloat_test_1);
+ CPPUNIT_TEST(toFloat_test_10);
+ CPPUNIT_TEST(toFloat_test_100);
+ CPPUNIT_TEST(toFloat_test_1000);
+ CPPUNIT_TEST(toFloat_test_10000);
+ CPPUNIT_TEST(toFloat_test_mix);
+ CPPUNIT_TEST(toFloat_test_1e99);
+ CPPUNIT_TEST(toFloat_test_1e_n99);
+ CPPUNIT_TEST(toFloat_test_1e308);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class toFloat
+
+// - lastIndexOf (tests)
+class lastIndexOf : public CppUnit::TestFixture
+{
+
+public:
+ void lastIndexOf_oustring(OUString const& _suStr, OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos)
+ {
+ // Algorithm
+ // search the string _suSearchStr (OUString) in the string _suStr.
+ // check if the _nExpectedResultPos occurs.
+
+ sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
+ }
+
+ void lastIndexOf_salunicode(OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos)
+ {
+ // Algorithm
+ // search the unicode char _suSearchChar (sal_Unicode) in the string _suStr.
+ // check if the _nExpectedResultPos occurs.
+
+ sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
+ }
+
+ void lastIndexOf_oustring_offset(OUString const& _suStr, OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset)
+ {
+ sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr, _nStartOffset);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
+ }
+
+ void lastIndexOf_salunicode_offset(OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset)
+ {
+ sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar, _nStartOffset);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("expected position is wrong", _nExpectedResultPos, nPos);
+ }
+
+ void lastIndexOf_test_oustring_offset_001()
+ {
+ // search for sun, start at the end, found (pos==0)
+ OUString aStr("sun java system");
+ lastIndexOf_oustring_offset(aStr, "sun", 0, aStr.getLength());
+ }
+
+ void lastIndexOf_test_oustring_offset_002()
+ {
+ // search for sun, start at pos = 3, found (pos==0)
+ lastIndexOf_oustring_offset("sun java system", "sun", 0, 3);
+ }
+
+ void lastIndexOf_test_oustring_offset_003()
+ {
+ // search for sun, start at pos = 2, found (pos==-1)
+ lastIndexOf_oustring_offset("sun java system", "sun", -1, 2);
+ }
+
+ void lastIndexOf_test_oustring_offset_004()
+ {
+ // search for sun, start at the end, found (pos==0)
+ lastIndexOf_oustring_offset("sun java system", "sun", -1, 1);
+ }
+
+ void lastIndexOf_test_oustring_001()
+ {
+ // search for sun, found (pos==0)
+ lastIndexOf_oustring("sun java system", "sun", 0);
+ }
+
+ void lastIndexOf_test_oustring_002()
+ {
+ // search for sun, found (pos==4)
+ lastIndexOf_oustring("the sun java system", "sun", 4);
+ }
+
+ void lastIndexOf_test_oustring_003()
+ {
+ // search for sun, found (pos==8)
+ lastIndexOf_oustring("the sun sun java system", "sun", 8);
+ }
+
+ void lastIndexOf_test_oustring_004()
+ {
+ // search for sun, found (pos==8)
+ lastIndexOf_oustring("the sun sun", "sun", 8);
+ }
+
+ void lastIndexOf_test_oustring_005()
+ {
+ // search for sun, found (pos==4)
+ lastIndexOf_oustring("the sun su", "sun", 4);
+ }
+
+ void lastIndexOf_test_oustring_006()
+ {
+ // search for sun, found (pos==-1)
+ lastIndexOf_oustring("the su su", "sun", -1);
+ }
+
+ void lastIndexOf_test_oustring_007()
+ {
+ // search for earth, not found (-1)
+ lastIndexOf_oustring("the su su", "earth", -1);
+ }
+
+ void lastIndexOf_test_oustring_008()
+ {
+ // search for earth, not found (-1)
+ lastIndexOf_oustring("", "earth", -1);
+ }
+
+ void lastIndexOf_test_oustring_009()
+ {
+ // search for earth, not found (-1)
+ lastIndexOf_oustring("", "", -1);
+
+ }
+
+ void lastIndexOf_test_salunicode_001()
+ {
+ // search for 's', found (19)
+ sal_Unicode suChar = L's';
+ lastIndexOf_salunicode("the sun sun java system", suChar, 19);
+ }
+
+ void lastIndexOf_test_salunicode_002()
+ {
+ // search for 'x', not found (-1)
+ sal_Unicode suChar = L'x';
+ lastIndexOf_salunicode("the sun sun java system", suChar, -1);
+ }
+
+ void lastIndexOf_test_salunicode_offset_001()
+ {
+ // search for 's', start from pos last char, found (19)
+ OUString aStr("the sun sun java system");
+ sal_Unicode cuChar = L's';
+ lastIndexOf_salunicode_offset(aStr, cuChar, 19, aStr.getLength());
+ }
+ void lastIndexOf_test_salunicode_offset_002()
+ {
+ // search for 's', start pos is last occur from search behind, found (17)
+ sal_Unicode cuChar = L's';
+ lastIndexOf_salunicode_offset("the sun sun java system", cuChar, 17, 19);
+ }
+ void lastIndexOf_test_salunicode_offset_003()
+ {
+ // search for 't', start pos is 1, found (0)
+ sal_Unicode cuChar = L't';
+ lastIndexOf_salunicode_offset("the sun sun java system", cuChar, 0, 1);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(lastIndexOf);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_001);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_002);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_003);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_004);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_005);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_006);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_007);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_008);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_009);
+
+ CPPUNIT_TEST(lastIndexOf_test_oustring_offset_001);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_offset_002);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_offset_003);
+ CPPUNIT_TEST(lastIndexOf_test_oustring_offset_004);
+
+ CPPUNIT_TEST(lastIndexOf_test_salunicode_001);
+ CPPUNIT_TEST(lastIndexOf_test_salunicode_002);
+
+ CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_001);
+ CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_002);
+ CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_003);
+
+ CPPUNIT_TEST_SUITE_END();
+}; // class lastIndexOf
+
+// - getToken (tests)
+class getToken : public CppUnit::TestFixture
+{
+
+public:
+ void getToken_000()
+ {
+ OUString suTokenStr;
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ suTokenStr.getToken( 0, ';', nIndex );
+ }
+ while ( nIndex >= 0 );
+ printf("Index %" SAL_PRIdINT32 "\n", nIndex);
+ // should not GPF
+ }
+
+ void getToken_001()
+ {
+ OUString suTokenStr("a;b");
+
+ sal_Int32 nIndex = 0;
+
+ OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken);
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
+ }
+
+ void getToken_002()
+ {
+ OUString suTokenStr("a;b.c");
+
+ sal_Int32 nIndex = 0;
+
+ OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken );
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken );
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'c'", OUString("c"), suToken );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
+ }
+
+ void getToken_003()
+ {
+ OUString suTokenStr("a;;b");
+
+ sal_Int32 nIndex = 0;
+
+ OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'a'", OUString("a"), suToken );
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.isEmpty());
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be a 'b'", OUString("b"), suToken );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
+ }
+
+ void getToken_004()
+ {
+ OUString suTokenStr("longer.then.ever.");
+
+ sal_Int32 nIndex = 0;
+
+ OUString suToken = suTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'longer'", OUString("longer"), suToken );
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'then'", OUString("then"), suToken );
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Token should be 'ever'", OUString("ever"), suToken );
+
+ /* OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
+ CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.isEmpty());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1), nIndex);
+ }
+
+ void getToken_005() {
+ OUString ab("ab");
+ sal_Int32 n = 0;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "token should be 'ab'", ab, ab.getToken(0, '-', n));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("n should be -1", static_cast<sal_Int32>(-1), n);
+ CPPUNIT_ASSERT_MESSAGE(
+ "token should be empty", ab.getToken(0, '-', n).isEmpty());
+ }
+
+ void getToken_006()
+ {
+ OUString suTokenStr;
+ auto pTokenStr = suTokenStr.getStr();
+ sal_uInt64 n64 = reinterpret_cast<sal_uInt64>(pTokenStr) / sizeof(sal_Unicode);
+ // Point either to 0x0, or to some random address -4GiB away from this string
+ sal_Int32 n = n64 > o3tl::make_unsigned(SAL_MAX_INT32) ? -SAL_MAX_INT32
+ : -static_cast<sal_Int32>(n64);
+ suTokenStr.getToken(0, ';', n);
+ // should not GPF with negative index
+ }
+
+ CPPUNIT_TEST_SUITE(getToken);
+ CPPUNIT_TEST(getToken_000);
+ CPPUNIT_TEST(getToken_001);
+ CPPUNIT_TEST(getToken_002);
+ CPPUNIT_TEST(getToken_003);
+ CPPUNIT_TEST(getToken_004);
+ CPPUNIT_TEST(getToken_005);
+ CPPUNIT_TEST(getToken_006);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getToken
+
+class convertToString: public CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(convertToString);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void convertToString::test() {
+ static constexpr OUStringLiteral utf16 = u"A\u00E4a";
+ OString s;
+ CPPUNIT_ASSERT(
+ OUString(utf16).convertToString(
+ &s, RTL_TEXTENCODING_UTF7,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)));
+ CPPUNIT_ASSERT_EQUAL(
+ OString(RTL_CONSTASCII_STRINGPARAM("A+AOQ-a")), s);
+}
+
+// - string construction & interning (tests)
+
+class construction : public CppUnit::TestFixture
+{
+public:
+ void construct()
+ {
+#ifdef RTL_INLINE_STRINGS
+ OUString aFoo( "foo" );
+ CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[0] == 'f');
+ CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[1] == 'o');
+ CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[2] == 'o');
+ CPPUNIT_ASSERT_MESSAGE("string length", aFoo.getLength() == 3);
+
+ OUString aBaa( "this is a very long string with a lot of long things inside it and it goes on and on and on forever etc." );
+ CPPUNIT_ASSERT_MESSAGE("string length", aBaa.getLength() == 104);
+ // Dig at the internals ... FIXME: should we have the bit-flag defines public ?
+ CPPUNIT_ASSERT_MESSAGE("string static flags", (aBaa.pData->refCount & 1<<30) != 0);
+#endif
+ }
+
+ void intern()
+ {
+ // The empty string is 'static' a special case ...
+ OUString().intern();
+ OUString::intern( "",strlen(""),RTL_TEXTENCODING_ASCII_US );
+
+ OUString aFoo( "foo" );
+ OUString aFooIntern = aFoo.intern();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "string contents", OUString("foo"), aFooIntern);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string length", static_cast<sal_Int32>(3), aFooIntern.getLength());
+ // We have to dup due to no atomic 'intern' bit-set operation
+ CPPUNIT_ASSERT_MESSAGE("intern dups", aFoo.pData != aFooIntern.pData);
+
+ // Test interning lots of things
+ int i;
+ static const int nSequence = 4096;
+ std::unique_ptr<OUString[]> pStrs(new OUString[nSequence]);
+ for (i = 0; i < nSequence; i++)
+ {
+ pStrs[i] = OUString( OUString::number( sqrt( static_cast<double>(i) ) ) ).intern();
+ }
+ for (i = 0; i < nSequence; i++)
+ {
+ OUString aNew = OUString( OUString::number( sqrt( static_cast<double>(i) ) ) ).intern();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("double intern failed",
+ pStrs[i].pData, aNew.pData);
+ }
+ }
+
+ CPPUNIT_TEST_SUITE(construction);
+ CPPUNIT_TEST(construct);
+ CPPUNIT_TEST(intern);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+class indexOfAscii: public CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(indexOfAscii);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void indexOfAscii::test() {
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString().indexOf(""));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString().lastIndexOf(""));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), OUString("foo").indexOf("foo"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), OUString("foo").lastIndexOf("foo"));
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(2), OUString("fofoobar").indexOf("foo"));
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(3), OUString("foofoofob").lastIndexOf("foo"));
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(3), OUString("foofoobar").indexOf("foo", 1));
+}
+
+class endsWith: public CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(endsWith);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void endsWith::test() {
+ CPPUNIT_ASSERT_EQUAL(true, OUString().endsWith(""));
+ CPPUNIT_ASSERT_EQUAL(false, OUString().endsWith("foo"));
+ CPPUNIT_ASSERT_EQUAL(true, OUString("bar").endsWith("bar"));
+ CPPUNIT_ASSERT_EQUAL(true, OUString("foobar").endsWith("bar"));
+ CPPUNIT_ASSERT_EQUAL(false, OUString("FOOBAR").endsWith("bar"));
+}
+
+class isEmpty: public CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(isEmpty);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void isEmpty::test() {
+ OUString aString;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Newly constructed string should be empty", true, aString.isEmpty() );
+
+ aString = "Not empty any more";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "String should not be empty", false, aString.isEmpty() );
+
+ aString.clear();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "aString.clear(), so should now be empty", true, aString.isEmpty() );
+}
+
+
+class createFromCodePoints: public CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(createFromCodePoints);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void createFromCodePoints::test() {
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(0),
+ OUString(static_cast< sal_uInt32 const * >(nullptr), 0).getLength());
+ sal_uInt32 cp[] = { 0, 0xD800, 0xFFFF, 0x10000, 0x10FFFF };
+ // non-const, to avoid loplugin:stringliteralvar
+ OUString s(cp, SAL_N_ELEMENTS(cp));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(7), s.getLength());
+ CPPUNIT_ASSERT_EQUAL(u'\0', s[0]);
+ CPPUNIT_ASSERT_EQUAL(u'\xD800', s[1]);
+ CPPUNIT_ASSERT_EQUAL(u'\xFFFF', s[2]);
+ CPPUNIT_ASSERT_EQUAL(u'\xD800', s[3]);
+ CPPUNIT_ASSERT_EQUAL(u'\xDC00', s[4]);
+ CPPUNIT_ASSERT_EQUAL(u'\xDBFF', s[5]);
+ CPPUNIT_ASSERT_EQUAL(u'\xDFFF', s[6]);
+}
+
+class iterateCodePoints: public CppUnit::TestFixture {
+public:
+ void testNotWellFormed();
+
+ CPPUNIT_TEST_SUITE(iterateCodePoints);
+ CPPUNIT_TEST(testNotWellFormed);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void iterateCodePoints::testNotWellFormed() {
+ static constexpr OUStringLiteral utf16 =
+ u"\U00010000A\U0010FFFF\xDDEF\xD9AB";
+ OUString s(utf16);
+ sal_Int32 i = 0;
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(7), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i, -1));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i, -1));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i, -1));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i, -1));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -1));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ i = 1;
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDC00), s.iterateCodePoints(&i, 2));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
+ i = 4;
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -3));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+}
+
+class convertFromString: public CppUnit::TestFixture {
+public:
+ void test();
+
+ CPPUNIT_TEST_SUITE(convertFromString);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void convertFromString::test() {
+ OUString t;
+ CPPUNIT_ASSERT(
+ !rtl_convertStringToUString(
+ &t.pData, RTL_CONSTASCII_STRINGPARAM("\x80"), RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
+ CPPUNIT_ASSERT(
+ !rtl_convertStringToUString(
+ &t.pData, RTL_CONSTASCII_STRINGPARAM("\xC0"), RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
+ CPPUNIT_ASSERT(
+ !rtl_convertStringToUString(
+ &t.pData, RTL_CONSTASCII_STRINGPARAM("\xFF"), RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
+ CPPUNIT_ASSERT(
+ rtl_convertStringToUString(
+ &t.pData, RTL_CONSTASCII_STRINGPARAM("abc"), RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
+ CPPUNIT_ASSERT_EQUAL( OUString("abc"), t );
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::number);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toInt);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toDouble);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::toFloat);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::lastIndexOf);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::getToken);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::convertToString);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::construction);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::indexOfAscii);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::endsWith);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::isEmpty);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::createFromCodePoints);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::iterateCodePoints);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_OUString::convertFromString);
+
+} // namespace rtl_OUString
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/oustring/rtl_ustr.cxx b/sal/qa/rtl/oustring/rtl_ustr.cxx
new file mode 100644
index 000000000..f5c405dfd
--- /dev/null
+++ b/sal/qa/rtl/oustring/rtl_ustr.cxx
@@ -0,0 +1,1080 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/cppunittraitshelper.hxx>
+#include <rtl/ustring.hxx>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+namespace rtl_ustr
+{
+
+ class compare : public CppUnit::TestFixture
+ {
+ void compare_001()
+ {
+ OUString aStr1;
+ OUString aStr2;
+
+ sal_Int32 nValue = rtl_ustr_compare( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002()
+ {
+ OUString aStr1("Line must be equal.");
+ OUString aStr2("Line must be equal.");
+
+ sal_Int32 nValue = rtl_ustr_compare( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_003()
+ {
+ OUString aStr1("Line must differ.");
+ OUString aStr2("Line foo bar, ok, differ.");
+
+ sal_Int32 nValue = rtl_ustr_compare( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(compare);
+ CPPUNIT_TEST(compare_001);
+ CPPUNIT_TEST(compare_002);
+ CPPUNIT_TEST(compare_003);
+ CPPUNIT_TEST_SUITE_END();
+}; // class compare
+
+ class compareIgnoreAsciiCase : public CppUnit::TestFixture
+ {
+ void compare_001()
+ {
+ OUString aStr1;
+ OUString aStr2;
+
+ sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002()
+ {
+ OUString aStr1("Line must be equal.");
+ OUString aStr2("Line must be equal.");
+
+ sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002_1()
+ {
+ OUString aStr1("Line must be equal.");
+ OUString aStr2("LINE MUST BE EQUAL.");
+
+ sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal (if case insensitive).", sal_Int32(0), nValue);
+ }
+
+ void compare_003()
+ {
+ OUString aStr1("Line must differ.");
+ OUString aStr2("Line foo bar, ok, differ.");
+
+ sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(compareIgnoreAsciiCase);
+ CPPUNIT_TEST(compare_001);
+ CPPUNIT_TEST(compare_002);
+ CPPUNIT_TEST(compare_002_1);
+ CPPUNIT_TEST(compare_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compareIgnoreAsciiCase
+
+ class shortenedCompareIgnoreAsciiCase_WithLength : public CppUnit::TestFixture
+ {
+ void compare_000()
+ {
+ rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( nullptr, 0, nullptr, 0, 0);
+ }
+
+ void compare_000_1()
+ {
+ OUString aStr1("Line must be equal.");
+ rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), nullptr, 0, 1);
+ }
+ void compare_001()
+ {
+ OUString aStr1;
+ OUString aStr2;
+
+ sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), aStr2.getStr(), aStr2.getLength(), aStr1.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002()
+ {
+ OUString aStr1("Line must be equal.");
+ OUString aStr2("Line must be equal.");
+
+ sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ aStr1.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void compare_002_1()
+ {
+ OUString aStr1("Line must be equal.");
+ OUString aStr2("LINE MUST BE EQUAL.");
+
+ sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ aStr1.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal (if case insensitive).", sal_Int32(0), nValue);
+ }
+
+ void compare_003()
+ {
+ OUString aStr1("Line must differ.");
+ OUString aStr2("Line foo bar, ok, differ.");
+
+ sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ 5);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal first 5 characters.", sal_Int32(0), nValue);
+ }
+
+ void compare_004()
+ {
+ OUString aStr1("Line must differ.");
+ OUString aStr2("Line foo bar, ok, differ.");
+
+ sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(),
+ aStr2.getStr(), aStr2.getLength(),
+ aStr1.getLength());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(shortenedCompareIgnoreAsciiCase_WithLength);
+ CPPUNIT_TEST(compare_000);
+ CPPUNIT_TEST(compare_000_1);
+ CPPUNIT_TEST(compare_001);
+ CPPUNIT_TEST(compare_002);
+ CPPUNIT_TEST(compare_002_1);
+ CPPUNIT_TEST(compare_003);
+ CPPUNIT_TEST(compare_004);
+ CPPUNIT_TEST_SUITE_END();
+}; // class compare
+
+//
+//
+// class hashCode : public CppUnit::TestFixture
+// {
+// void hashCode_000()
+// {
+// sal_Int32 nHashCode = rtl_ustr_hashCode( nullptr );
+// volatile int dummy = 0;
+// }
+//
+// void hashCode_001()
+// {
+// OString aStr1 = "Line for a hashCode.";
+// sal_Int32 nHashCode = rtl_ustr_hashCode( aStr1.getStr() );
+// printf("hashcode: %d\n", nHashCode);
+// // CPPUNIT_ASSERT_MESSAGE("failed.", nValue == 0);
+// }
+//
+// void hashCode_002()
+// {
+// OString aStr1 = "Line for a hashCode.";
+// sal_Int32 nHashCode1 = rtl_ustr_hashCode( aStr1.getStr() );
+//
+// OString aStr2 = "Line for a hashCode.";
+// sal_Int32 nHashCode2 = rtl_ustr_hashCode( aStr2.getStr() );
+//
+// CPPUNIT_ASSERT_MESSAGE("hashcodes must be equal.", nHashCode1 == nHashCode2 );
+// }
+//
+// void hashCode_003()
+// {
+// OString aStr1 = "Line for a hashCode.";
+// sal_Int32 nHashCode1 = rtl_ustr_hashCode( aStr1.getStr() );
+//
+// OString aStr2 = "Line for another hashcode.";
+// sal_Int32 nHashCode2 = rtl_ustr_hashCode( aStr2.getStr() );
+//
+// CPPUNIT_ASSERT_MESSAGE("hashcodes must differ.", nHashCode1 != nHashCode2 );
+// }
+//
+// // Change the following lines only, if you add, remove or rename
+// // member functions of the current class,
+// // because these macros are need by auto register mechanism.
+//
+// CPPUNIT_TEST_SUITE(hashCode);
+// CPPUNIT_TEST(hashCode_000);
+// CPPUNIT_TEST(hashCode_001);
+// CPPUNIT_TEST(hashCode_002);
+// CPPUNIT_TEST(hashCode_003);
+// CPPUNIT_TEST_SUITE_END();
+// }; // class compare
+
+ class indexOfChar : public CppUnit::TestFixture
+ {
+ void indexOfChar_000()
+ {
+ sal_Int32 nIndex = rtl_ustr_indexOfChar( u"", 0 );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Trailing zero character is not part of the string",
+ sal_Int32(-1), nIndex);
+ }
+
+ void indexOfChar_001()
+ {
+ OUString aStr1("Line for an indexOfChar.");
+
+ sal_Int32 nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'L' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(0), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'i' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(1), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'n' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(2), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'e' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(3), nIndex);
+ }
+
+ void indexOfChar_002()
+ {
+ OUString aStr1("Line for an indexOfChar.");
+ sal_Int32 nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'y' );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(indexOfChar);
+ CPPUNIT_TEST(indexOfChar_000);
+ CPPUNIT_TEST(indexOfChar_001);
+ CPPUNIT_TEST(indexOfChar_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class indexOfChar
+
+ class lastIndexOfChar : public CppUnit::TestFixture
+ {
+ void lastIndexOfChar_000()
+ {
+ sal_Int32 nIndex = rtl_ustr_lastIndexOfChar( u"", 0 );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Trailing zero character is not part of the string",
+ sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfChar_001()
+ {
+ OUString aStr1("Line for a lastIndexOfChar.");
+
+ sal_Int32 nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'C' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(22), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'h' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(23), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'a' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(24), nIndex);
+
+ /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'r' );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(25), nIndex);
+ }
+
+ void lastIndexOfChar_002()
+ {
+ OUString aStr1("Line for a lastIndexOfChar.");
+ sal_Int32 nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'y' );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(lastIndexOfChar);
+ CPPUNIT_TEST(lastIndexOfChar_000);
+ CPPUNIT_TEST(lastIndexOfChar_001);
+ CPPUNIT_TEST(lastIndexOfChar_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class lastIndexOfChar
+
+ class indexOfStr : public CppUnit::TestFixture
+ {
+ void indexOfStr_000()
+ {
+ OUString aStr1("Line for an indexOfStr.");
+ sal_Int32 nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), u"" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("an empty substring is always not findable",
+ sal_Int32(-1), nIndex);
+ }
+
+ void indexOfStr_001()
+ {
+ OUString aStr1("Line for an indexOfStr.");
+
+ OUString suSearch("Line");
+ sal_Int32 nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(0), nIndex);
+
+ suSearch = "for";
+ nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(5), nIndex);
+
+ suSearch = "a";
+ /* sal_Int32 */ nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(9), nIndex);
+
+ suSearch = "an index";
+ /* sal_Int32 */ nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(9), nIndex);
+ }
+
+ void indexOfStr_002()
+ {
+ OUString aStr1("Line for an indexOfStr.");
+ OUString suSearch("not exist");
+ sal_Int32 nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(indexOfStr);
+ CPPUNIT_TEST(indexOfStr_000);
+ CPPUNIT_TEST(indexOfStr_001);
+ CPPUNIT_TEST(indexOfStr_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class compare
+
+ class lastIndexOfStr : public CppUnit::TestFixture
+ {
+ void lastIndexOfStr_000()
+ {
+ OUString aStr1("Line for a lastIndexOfStr.");
+ sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), u"" );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("an empty substring is always not findable",
+ sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfStr_001()
+ {
+ OUString aStr1("Line for a lastIndexOfStr.");
+ OUString aSearchStr("Index");
+
+ sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(15), nIndex);
+
+ /* OString */ aSearchStr = OUString("Line");
+ /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(0), nIndex);
+
+ /* OString */ aSearchStr = OUString();
+ /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfStr_002()
+ {
+ OUString aStr1("Line for a lastIndexOfStr.");
+ OUString aSearchStr("foo");
+ sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(-1), nIndex);
+ }
+
+ void lastIndexOfStr_003()
+ {
+ OUString aStr1("Line for a lastIndexOfStr.");
+ OUString aSearchStr("O");
+ sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index is wrong.", sal_Int32(20), nIndex);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(lastIndexOfStr);
+ CPPUNIT_TEST(lastIndexOfStr_000);
+ CPPUNIT_TEST(lastIndexOfStr_001);
+ CPPUNIT_TEST(lastIndexOfStr_002);
+ CPPUNIT_TEST(lastIndexOfStr_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class lastIndexOfStr
+
+ class replaceChar : public CppUnit::TestFixture
+ {
+ void replaceChar_001()
+ {
+ sal_Unicode pStr[] = u"replace char.";
+ OUString aShouldStr1("ruplacu char.");
+
+ rtl_ustr_replaceChar( pStr, 'e', 'u' );
+ OUString suStr(pStr);
+
+ CPPUNIT_ASSERT_MESSAGE("replace failed", aShouldStr1.equals(suStr));
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(replaceChar);
+ CPPUNIT_TEST(replaceChar_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class replaceChar_WithLength : public CppUnit::TestFixture
+ {
+ void replaceChar_WithLength_000()
+ {
+ rtl_ustr_replaceChar_WithLength( nullptr, 0, 0, 0 );
+ }
+
+ void replaceChar_WithLength_001()
+ {
+ sal_Unicode pStr[] = u"replace char.";
+ OUString aShouldStr1("ruplace char.");
+
+ rtl_ustr_replaceChar_WithLength( pStr, 6, 'e', 'u' );
+ OUString suStr(pStr);
+
+ CPPUNIT_ASSERT_MESSAGE("replace failed", aShouldStr1.equals(suStr));
+ }
+
+ void replaceChar_WithLength_002()
+ {
+ sal_Unicode pStr[] = u"eeeeeeeeeeeee";
+ OUString aShouldStr1("uuuuuueeeeeee");
+
+ rtl_ustr_replaceChar_WithLength( pStr, 6, 'e', 'u' );
+ OUString suStr(pStr);
+
+ CPPUNIT_ASSERT_MESSAGE("replace failed", aShouldStr1.equals(suStr));
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(replaceChar_WithLength);
+ CPPUNIT_TEST(replaceChar_WithLength_000);
+ CPPUNIT_TEST(replaceChar_WithLength_001);
+ CPPUNIT_TEST(replaceChar_WithLength_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiLowerCase : public CppUnit::TestFixture
+ {
+ void toAsciiLowerCase_001()
+ {
+ sal_Unicode pStr[] = u"CHANGE THIS TO ASCII LOWER CASE.";
+ OUString aShouldStr1("change this to ascii lower case.");
+
+ rtl_ustr_toAsciiLowerCase( pStr );
+ OUString suStr(pStr);
+
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(suStr));
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiLowerCase);
+ CPPUNIT_TEST(toAsciiLowerCase_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiLowerCase_WithLength : public CppUnit::TestFixture
+ {
+ void toAsciiLowerCase_WithLength_000()
+ {
+ rtl_ustr_toAsciiLowerCase_WithLength( nullptr, 0 );
+ }
+
+ void toAsciiLowerCase_WithLength_001()
+ {
+ sal_Unicode pStr[] = u"CHANGE THIS TO ASCII LOWER CASE.";
+ OUString aShouldStr1("change thiS TO ASCII LOWER CASE.");
+
+ rtl_ustr_toAsciiLowerCase_WithLength( pStr, 10 );
+ OUString suStr(pStr);
+
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(suStr));
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiLowerCase_WithLength);
+ CPPUNIT_TEST(toAsciiLowerCase_WithLength_000);
+ CPPUNIT_TEST(toAsciiLowerCase_WithLength_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiUpperCase : public CppUnit::TestFixture
+ {
+ void toAsciiUpperCase_001()
+ {
+ sal_Unicode pStr[] = u"change this to ascii upper case.";
+ OUString aShouldStr1("CHANGE THIS TO ASCII UPPER CASE.");
+
+ rtl_ustr_toAsciiUpperCase( pStr );
+ OUString suStr(pStr);
+
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(suStr));
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiUpperCase);
+ CPPUNIT_TEST(toAsciiUpperCase_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class toAsciiUpperCase_WithLength : public CppUnit::TestFixture
+ {
+ void toAsciiUpperCase_WithLength_000()
+ {
+ rtl_ustr_toAsciiUpperCase_WithLength( nullptr, 0 );
+ }
+
+ void toAsciiUpperCase_WithLength_001()
+ {
+ sal_Unicode pStr[] = u"change this to ascii lower case.";
+ OUString aShouldStr1("CHANGE THIs to ascii lower case.");
+
+ rtl_ustr_toAsciiUpperCase_WithLength( pStr, 10 );
+ OUString suStr(pStr);
+
+ // printf("Uppercase with length: '%s'\n", aStr1.getStr());
+ CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(suStr));
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(toAsciiUpperCase_WithLength);
+ CPPUNIT_TEST(toAsciiUpperCase_WithLength_000);
+ CPPUNIT_TEST(toAsciiUpperCase_WithLength_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class replaceChar
+
+ class trim_WithLength : public CppUnit::TestFixture
+ {
+ void trim_WithLength_000()
+ {
+ rtl_ustr_trim_WithLength(nullptr, 0);
+ // should not GPF
+ }
+
+ void trim_WithLength_000_1()
+ {
+ sal_Unicode pStr[] = u" trim this";
+
+ rtl_ustr_trim_WithLength( pStr, 0 );
+ }
+
+ void trim_WithLength_001()
+ {
+ sal_Unicode pStr[] = u" trim this";
+
+ rtl_ustr_trim_WithLength( pStr, 2 );
+
+ CPPUNIT_ASSERT_MESSAGE("string should be empty", OUString(pStr).isEmpty());
+ }
+
+ void trim_WithLength_002()
+ {
+ sal_Unicode pStr[] = u"trim this";
+
+ rtl_ustr_trim_WithLength( pStr, 5 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim'", sal_Int32(4), OUString(pStr).getLength());
+ }
+
+ void trim_WithLength_003()
+ {
+ sal_Unicode pStr[] = u" trim this";
+
+ rtl_ustr_trim_WithLength( pStr, 11 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim'", sal_Int32(4), OUString(pStr).getLength());
+ }
+
+ void trim_WithLength_004()
+ {
+ sal_Unicode pStr[] = u"\r\n\t \n\r trim \n this";
+
+ rtl_ustr_trim_WithLength( pStr, 17 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim'", sal_Int32(4), OUString(pStr).getLength());
+ }
+
+ void trim_WithLength_005()
+ {
+ sal_Unicode pStr[] = u"\r\n\t \n\r trim \t this \n\r\t\t ";
+
+ rtl_ustr_trim_WithLength( pStr, std::size(pStr) - 1 );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'trim \\t this'", sal_Int32(11), OUString(pStr).getLength());
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(trim_WithLength);
+ CPPUNIT_TEST(trim_WithLength_000);
+ CPPUNIT_TEST(trim_WithLength_000_1);
+ CPPUNIT_TEST(trim_WithLength_001);
+ CPPUNIT_TEST(trim_WithLength_002);
+ CPPUNIT_TEST(trim_WithLength_003);
+ CPPUNIT_TEST(trim_WithLength_004);
+ CPPUNIT_TEST(trim_WithLength_005);
+ CPPUNIT_TEST_SUITE_END();
+ };
+
+ class valueOfChar : public CppUnit::TestFixture
+ {
+ void valueOfChar_001()
+ {
+ sal_Unicode pStr[RTL_USTR_MAX_VALUEOFCHAR];
+ rtl_ustr_valueOfChar(pStr, 'A');
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("string should contain 'A'", u'A', pStr[0]);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(valueOfChar);
+ CPPUNIT_TEST(valueOfChar_001);
+ CPPUNIT_TEST_SUITE_END();
+ };
+
+ class ascii_compare_WithLength : public CppUnit::TestFixture
+ {
+ void zero_length()
+ {
+ sal_Unicode pUnicode[] = {0xffff, 0xffff};
+ char const pAscii[] = "reference";
+
+ sal_Int32 value = rtl_ustr_ascii_compare_WithLength(pUnicode, 0, pAscii);
+ CPPUNIT_ASSERT_LESS(sal_Int32(0), value);
+ }
+
+ void equal_ascii_shorter()
+ {
+ OUString refStr("referenceString");
+ char const pAscii[] = "reference";
+
+ sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii);
+ CPPUNIT_ASSERT_GREATER(sal_Int32(0), value);
+ }
+
+ void equal_ascii_shorter_asciiLength()
+ {
+ OUString refStr("referenceString");
+ char const pAscii[] = "reference";
+
+ sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, rtl_str_getLength(pAscii), pAscii);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), value);
+ }
+
+ void equal_ref_shorter()
+ {
+ OUString refStr("reference");
+ char const pAscii[] = "referenceString";
+
+ sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii);
+ CPPUNIT_ASSERT_LESS(sal_Int32(0), value);
+ }
+
+ void equal()
+ {
+ OUString refStr("reference");
+ char const pAscii[] = "reference";
+
+ sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), value);
+ }
+
+ void unequal_reference_bigger()
+ {
+ OUString refStr("defghi");
+ char const pAscii[] = "abc";
+
+ sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii);
+ CPPUNIT_ASSERT_GREATER(sal_Int32(0), value);
+ }
+
+ void unequal_ascii_bigger()
+ {
+ OUString refStr("abc");
+ char const pAscii[] = "defghi";
+
+ sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii);
+
+ CPPUNIT_ASSERT_LESS(sal_Int32(0), value);
+ }
+
+ CPPUNIT_TEST_SUITE(ascii_compare_WithLength);
+ CPPUNIT_TEST(zero_length);
+ CPPUNIT_TEST(equal_ascii_shorter);
+ CPPUNIT_TEST(equal_ascii_shorter_asciiLength);
+ CPPUNIT_TEST(equal_ref_shorter);
+ CPPUNIT_TEST(equal);
+ CPPUNIT_TEST(unequal_reference_bigger);
+ CPPUNIT_TEST(unequal_ascii_bigger);
+ CPPUNIT_TEST_SUITE_END();
+ };
+
+ class ascii_shortenedCompareIgnoreAsciiCase_WithLength : public CppUnit::TestFixture
+ {
+ void ascii_shortenedCompareIgnoreAsciiCase_WithLength_000()
+ {
+ rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( nullptr, 0, "", 0);
+ // should not GPF
+ }
+
+ void ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_1()
+ {
+ OUString aStr1("Line must be equal.");
+ rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), "", 0);
+ // should not GPF
+ }
+ void ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_2()
+ {
+ OUString aStr1("Line must be equal.");
+ OString sStr2 = "Line is shorter.";
+ rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), sStr2.getLength(), sStr2.getStr(), 0);
+ // should not GPF
+ }
+ void ascii_shortenedCompareIgnoreAsciiCase_WithLength_001()
+ {
+ OUString suStr1;
+ OString sStr2;
+
+ sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( suStr1.getStr(), 0, sStr2.getStr(), 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_shortenedCompareIgnoreAsciiCase_WithLength_002()
+ {
+ OUString suStr1("Line must be equal.");
+ OString sStr2 = "Line must be equal.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr(), sStr2.getLength());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_shortenedCompareIgnoreAsciiCase_WithLength_003()
+ {
+ OUString suStr1("Line must differ.");
+ OString sStr2 = "Line must be differ and longer.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr(), sStr2.getLength());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(ascii_shortenedCompareIgnoreAsciiCase_WithLength);
+ CPPUNIT_TEST(ascii_shortenedCompareIgnoreAsciiCase_WithLength_000);
+ CPPUNIT_TEST(ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_1);
+ CPPUNIT_TEST(ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_2);
+ CPPUNIT_TEST(ascii_shortenedCompareIgnoreAsciiCase_WithLength_001);
+ CPPUNIT_TEST(ascii_shortenedCompareIgnoreAsciiCase_WithLength_002);
+ CPPUNIT_TEST(ascii_shortenedCompareIgnoreAsciiCase_WithLength_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class ascii_shortenedCompareIgnoreAsciiCase_WithLength
+
+ class ascii_compareIgnoreAsciiCase_WithLength : public CppUnit::TestFixture
+ {
+ void ascii_compareIgnoreAsciiCase_WithLength_000()
+ {
+ rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( nullptr, 0, "");
+ // should not GPF
+ }
+
+ void ascii_compareIgnoreAsciiCase_WithLength_000_1()
+ {
+ OUString aStr1("Line must be equal.");
+ rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( aStr1.getStr(), 0, "");
+ // should not GPF
+ }
+ void ascii_compareIgnoreAsciiCase_WithLength_000_2()
+ {
+ OUString aStr1("Line must be equal.");
+ OString sStr2 = "Line is shorter.";
+ rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( aStr1.getStr(), sStr2.getLength(), sStr2.getStr());
+ // should not GPF
+ }
+ void ascii_compareIgnoreAsciiCase_WithLength_001()
+ {
+ OUString suStr1;
+ OString sStr2;
+
+ sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( suStr1.getStr(), 0, sStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compareIgnoreAsciiCase_WithLength failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_compareIgnoreAsciiCase_WithLength_002()
+ {
+ OUString suStr1("Line must be equal.");
+ OString sStr2 = "Line must be equal.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_compareIgnoreAsciiCase_WithLength_003()
+ {
+ OUString suStr1("Line must differ.");
+ OString sStr2 = "Line must be differ and longer.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(ascii_compareIgnoreAsciiCase_WithLength);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_WithLength_000);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_WithLength_000_1);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_WithLength_000_2);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_WithLength_001);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_WithLength_002);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_WithLength_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class ascii_compareIgnoreAsciiCase_WithLength
+
+ class ascii_compare : public CppUnit::TestFixture
+ {
+ void ascii_compare_001()
+ {
+ OUString suStr1;
+ OString sStr2;
+
+ sal_Int32 nValue = rtl_ustr_ascii_compare( suStr1.getStr(), sStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_compare_002()
+ {
+ OUString suStr1("Line must be equal.");
+ OString sStr2 = "Line must be equal.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_compare( suStr1.getStr(), sStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_compare_003()
+ {
+ OUString suStr1("Line must differ.");
+ OString sStr2 = "Line foo bar, ok, differ.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_compare( suStr1.getStr(), sStr2.getStr());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(ascii_compare);
+ CPPUNIT_TEST(ascii_compare_001);
+ CPPUNIT_TEST(ascii_compare_002);
+ CPPUNIT_TEST(ascii_compare_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class ascii_compare
+
+ class ascii_compareIgnoreAsciiCase : public CppUnit::TestFixture
+ {
+ void ascii_compareIgnoreAsciiCase_001()
+ {
+ OUString suStr1;
+ OString sStr2;
+
+ sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_compareIgnoreAsciiCase_002()
+ {
+ OUString suStr1("Line must be equal.");
+ OString sStr2 = "Line must be equal.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal.", sal_Int32(0), nValue);
+ }
+
+ void ascii_compareIgnoreAsciiCase_002_1()
+ {
+ OUString suStr1("Line must be equal, when ignore case.");
+ OString sStr2 = "LINE MUST BE EQUAL, WHEN IGNORE CASE.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("compare failed, strings are equal (if case insensitive).", sal_Int32(0), nValue);
+ }
+
+ void ascii_compareIgnoreAsciiCase_003()
+ {
+ OUString suStr1("Line must differ.");
+ OString sStr2 = "Line foo bar, ok, differ.";
+
+ sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr());
+ CPPUNIT_ASSERT_MESSAGE("compare failed, strings differ.", nValue != 0);
+ }
+
+ //! LLA: some more tests with some high level strings
+
+ // void ascii_compareIgnoreAsciiCase_001()
+ // {
+ // OUString suStr1("change this to ascii upper case.");
+ // OUString aShouldStr1("CHANGE THIS TO ASCII UPPER CASE.");
+ //
+ // sal_uInt32 nLength = suStr1.getLength() * sizeof(sal_Unicode);
+ // sal_Unicode* pStr = (sal_Unicode*) malloc(nLength + sizeof(sal_Unicode)); // length + null terminator
+ // CPPUNIT_ASSERT_MESSAGE("can't get memory for test", pStr != nullptr);
+ // memset(pStr, 0, nLength + sizeof(sal_Unicode));
+ // memcpy(pStr, suStr1.getStr(), nLength);
+ //
+ // rtl_ustr_ascii_compareIgnoreAsciiCase( pStr );
+ // OUString suStr(pStr, suStr1.getLength());
+ //
+ // CPPUNIT_ASSERT_MESSAGE("failed", aShouldStr1.equals(suStr));
+ // free(pStr);
+ // }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(ascii_compareIgnoreAsciiCase);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_001);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_002);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_002_1);
+ CPPUNIT_TEST(ascii_compareIgnoreAsciiCase_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class ascii_compareIgnoreAsciiCase
+
+ // sample out of inc/rtl/ustring.hxx
+ // rtl_uString * pToken = nullptr;
+ // sal_Int32 nIndex = 0;
+ // do
+ // {
+ // ...
+ // nIndex = rtl_uString_getToken(&pToken, pStr, 0, ';', nIndex);
+ // ...
+ // }
+ // while (nIndex >= 0);
+
+ class getToken : public CppUnit::TestFixture
+ {
+ void getToken_000()
+ {
+ OUString s("a;b;c");
+ // Replace the string in place
+ const sal_Int32 i = rtl_uString_getToken(&s.pData, s.pData, 1, ';', 0);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), i);
+ CPPUNIT_ASSERT_EQUAL(OUString("b"), s);
+ }
+
+ CPPUNIT_TEST_SUITE(getToken);
+ CPPUNIT_TEST(getToken_000);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class ascii_compareIgnoreAsciiCase
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::compare);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::compareIgnoreAsciiCase);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::ascii_compare_WithLength);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::shortenedCompareIgnoreAsciiCase_WithLength);
+// CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::hashCode);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::indexOfChar);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::lastIndexOfChar);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::indexOfStr);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::lastIndexOfStr);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::replaceChar);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::replaceChar_WithLength);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::toAsciiLowerCase);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::toAsciiLowerCase_WithLength);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::toAsciiUpperCase);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::toAsciiUpperCase_WithLength);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::trim_WithLength);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::valueOfChar);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::ascii_compare);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::ascii_compareIgnoreAsciiCase);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::ascii_compareIgnoreAsciiCase_WithLength);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::ascii_shortenedCompareIgnoreAsciiCase_WithLength);
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ustr::getToken);
+
+} // namespace rtl_ustr
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/oustring/rtl_ustr.xsce b/sal/qa/rtl/oustring/rtl_ustr.xsce
new file mode 100644
index 000000000..c7b5c99f3
--- /dev/null
+++ b/sal/qa/rtl/oustring/rtl_ustr.xsce
@@ -0,0 +1,50 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+# functions which are gpf
+
+rtl_ustr.compare.compare_000
+rtl_ustr.compare.compare_000_1
+
+rtl_ustr.compareIgnoreAsciiCase.compare_000
+rtl_ustr.compareIgnoreAsciiCase.compare_000_1
+
+rtl_ustr.indexOfChar.indexOfChar_000
+
+rtl_ustr.lastIndexOfChar.lastIndexOfChar_000
+
+rtl_ustr.indexOfStr.indexOfStr_000
+
+rtl_ustr.lastIndexOfStr.lastIndexOfStr_000
+
+rtl_ustr.replaceChar.replaceChar_000
+
+rtl_ustr.replaceChar_WithLength.replaceChar_WithLength_000_1
+
+rtl_ustr.toAsciiLowerCase.toAsciiLowerCase_000
+
+rtl_ustr.toAsciiUpperCase.toAsciiUpperCase_000
+
+rtl_ustr.valueOfChar.valueOfChar_000
+
+rtl_ustr.ascii_compare.ascii_compare_000
+rtl_ustr.ascii_compare.ascii_compare_000_1
+rtl_ustr.ascii_compareIgnoreAsciiCase.ascii_compareIgnoreAsciiCase_000
+rtl_ustr.ascii_compareIgnoreAsciiCase.ascii_compareIgnoreAsciiCase_000_1
+rtl_ustr.ascii_compareIgnoreAsciiCase_WithLength.ascii_compareIgnoreAsciiCase_WithLength_000
+rtl_ustr.ascii_compareIgnoreAsciiCase_WithLength.ascii_compareIgnoreAsciiCase_WithLength_000_1
+
diff --git a/sal/qa/rtl/oustringbuffer/test_oustringbuffer_appendchar.cxx b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_appendchar.cxx
new file mode 100644
index 000000000..f5168b60d
--- /dev/null
+++ b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_appendchar.cxx
@@ -0,0 +1,43 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/cppunittraitshelper.hxx>
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/ustrbuf.hxx>
+
+namespace test::oustringbuffer {
+
+class AppendChar: public CppUnit::TestFixture {
+private:
+ void testAppendChar();
+
+ CPPUNIT_TEST_SUITE(AppendChar);
+ CPPUNIT_TEST(testAppendChar);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void AppendChar::testAppendChar() {
+ // Check that append('a') does not unexpectedly pick
+ // append(sal_Int32 i, sal_Int16 radix = 10):
+ OUStringBuffer s;
+ s.append('a');
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), s.getLength());
+ CPPUNIT_ASSERT_EQUAL(u'a', s[0]);
+}
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustringbuffer::AppendChar);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/oustringbuffer/test_oustringbuffer_appenduninitialized.cxx b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_appenduninitialized.cxx
new file mode 100644
index 000000000..7530d6a32
--- /dev/null
+++ b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_appenduninitialized.cxx
@@ -0,0 +1,66 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/ustrbuf.hxx>
+#include <sal/types.h>
+
+namespace {
+
+class Test: public CppUnit::TestFixture {
+private:
+ void testEmpty();
+
+ void testNonEmpty();
+
+ void testZero();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testEmpty);
+ CPPUNIT_TEST(testNonEmpty);
+ CPPUNIT_TEST(testZero);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::testEmpty() {
+ OUStringBuffer s;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), s.getLength());
+ sal_Unicode * p = s.appendUninitialized(5);
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<void const *>(s.getStr()), static_cast<void const *>(p));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), s.getLength());
+}
+
+void Test::testNonEmpty() {
+ OUStringBuffer s("ab");
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), s.getLength());
+ sal_Unicode * p = s.appendUninitialized(5);
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<void const *>(s.getStr() + 2),
+ static_cast<void const *>(p));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(7), s.getLength());
+}
+
+void Test::testZero() {
+ OUStringBuffer s;
+ sal_Unicode * p = s.appendUninitialized(0);
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<void const *>(s.getStr()), static_cast<void const *>(p));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), s.getLength());
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/oustringbuffer/test_oustringbuffer_assign.cxx b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_assign.cxx
new file mode 100644
index 000000000..3c3f436ee
--- /dev/null
+++ b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_assign.cxx
@@ -0,0 +1,92 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <o3tl/cppunittraitshelper.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+
+namespace
+{
+class Test : public CppUnit::TestFixture
+{
+private:
+ void test()
+ {
+ OUStringBuffer b1;
+ OUString s1("123456789012345");
+ b1 = s1;
+ CPPUNIT_ASSERT_EQUAL(s1, b1.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b1.getCapacity());
+ OUString s2("abc");
+ b1 = s2;
+ CPPUNIT_ASSERT_EQUAL(s2, b1.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b1.getCapacity());
+ OUString s3("1234567890123456");
+ b1 = s3;
+ CPPUNIT_ASSERT_EQUAL(s3, b1.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(32), b1.getCapacity());
+ OUStringBuffer b2;
+ b2 = "123456789012345";
+ CPPUNIT_ASSERT_EQUAL(s1, b2.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b2.getCapacity());
+ b2 = "abc";
+ CPPUNIT_ASSERT_EQUAL(s2, b2.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b2.getCapacity());
+ b2 = "1234567890123456";
+ CPPUNIT_ASSERT_EQUAL(s3, b2.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(32), b2.getCapacity());
+ OUStringBuffer b3;
+ b3 = u"123456789012345";
+ CPPUNIT_ASSERT_EQUAL(s1, b3.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b3.getCapacity());
+ b3 = u"abc";
+ CPPUNIT_ASSERT_EQUAL(s2, b3.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b3.getCapacity());
+ b3 = u"1234567890123456";
+ CPPUNIT_ASSERT_EQUAL(s3, b3.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(32), b3.getCapacity());
+ OUStringBuffer b4;
+ b4 = OUStringLiteral(u"1") + "23456789012345";
+ CPPUNIT_ASSERT_EQUAL(s1, b4.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b4.getCapacity());
+ b4 = OUStringLiteral(u"a") + "bc";
+ CPPUNIT_ASSERT_EQUAL(s2, b4.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(16), b4.getCapacity());
+ b4 = OUStringLiteral(u"1") + "234567890123456";
+ CPPUNIT_ASSERT_EQUAL(s3, b4.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(32), b4.getCapacity());
+ b4 = OUStringChar('a');
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), b4.getLength());
+ CPPUNIT_ASSERT_EQUAL(u'a', b4.getStr()[0]);
+ CPPUNIT_ASSERT_EQUAL(u'\0', b4.getStr()[1]);
+ b4 = std::u16string_view(u"abc").substr(
+ 0, 2); // avoid the string_view accidentally being NUL-terminated
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), b4.getLength());
+ CPPUNIT_ASSERT_EQUAL(u'a', b4.getStr()[0]);
+ CPPUNIT_ASSERT_EQUAL(u'b', b4.getStr()[1]);
+ CPPUNIT_ASSERT_EQUAL(u'\0', b4.getStr()[2]);
+ }
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(test);
+ CPPUNIT_TEST_SUITE_END();
+};
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sal/qa/rtl/oustringbuffer/test_oustringbuffer_tostring.cxx b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_tostring.cxx
new file mode 100644
index 000000000..d942480d1
--- /dev/null
+++ b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_tostring.cxx
@@ -0,0 +1,61 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+
+namespace test::oustringbuffer {
+
+class ToString: public CppUnit::TestFixture {
+private:
+ void testEmptyToString();
+ void testToString();
+
+ CPPUNIT_TEST_SUITE(ToString);
+ CPPUNIT_TEST(testEmptyToString);
+ CPPUNIT_TEST(testToString);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustringbuffer::ToString);
+
+void test::oustringbuffer::ToString::testEmptyToString() {
+ OUStringBuffer sb;
+ OUString str = sb.toString();
+ CPPUNIT_ASSERT_EQUAL(OUString(), str);
+}
+
+void test::oustringbuffer::ToString::testToString() {
+ OUStringBuffer sb("test string");
+ OUString str = sb.toString();
+ CPPUNIT_ASSERT_EQUAL( OUString("test string"), str );
+ // returned OUString must be independent from sb
+ sb.append( 'a' );
+ CPPUNIT_ASSERT_EQUAL( OUString("test string"), str );
+ sb.setLength(0);
+ CPPUNIT_ASSERT_EQUAL( OUString("test string"), str );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/oustringbuffer/test_oustringbuffer_utf32.cxx b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_utf32.cxx
new file mode 100644
index 000000000..764b03d8c
--- /dev/null
+++ b/sal/qa/rtl/oustringbuffer/test_oustringbuffer_utf32.cxx
@@ -0,0 +1,121 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+
+namespace test::oustringbuffer {
+
+class Utf32: public CppUnit::TestFixture {
+private:
+ void appendUtf32();
+
+ void insertUtf32();
+
+ CPPUNIT_TEST_SUITE(Utf32);
+ CPPUNIT_TEST(appendUtf32);
+ CPPUNIT_TEST(insertUtf32);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustringbuffer::Utf32);
+
+namespace {
+
+void appendString(OStringBuffer & buffer, OUString const & string) {
+ buffer.append('"');
+ for (int i = 0; i < string.getLength(); ++i) {
+ buffer.append("\\u");
+ sal_Unicode c = string[i];
+ if (c < 0x1000) {
+ buffer.append('0');
+ if (c < 0x100) {
+ buffer.append('0');
+ if (c < 0x10) {
+ buffer.append('0');
+ }
+ }
+ }
+ buffer.append(
+ static_cast< sal_Int32 >(c), static_cast< sal_Int16 >(16));
+ }
+ buffer.append('"');
+}
+
+void createMessage(
+ OStringBuffer & message, OUString const & string1,
+ OUString const & string2)
+{
+ message.setLength(0);
+ appendString(message, string1);
+ message.append(" vs. ");
+ appendString(message, string2);
+}
+
+}
+
+void test::oustringbuffer::Utf32::appendUtf32() {
+ int const str1Len = 3;
+ sal_Unicode const str1[str1Len] = { 'a', 'b', 'c' };
+ static constexpr OUStringLiteral str2 = u"abcd";
+ static constexpr OUStringLiteral str3 = u"abcd\U00010000";
+ OStringBuffer message;
+ OUStringBuffer buf1(std::u16string_view(str1, str1Len));
+ buf1.appendUtf32('d');
+ OUString res1(buf1.makeStringAndClear());
+ createMessage(message, res1, str2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ message.getStr(), OUString(str2), res1);
+ OUStringBuffer buf2(str2);
+ buf2.appendUtf32(0x10000);
+ OUString res2(buf2.makeStringAndClear());
+ createMessage(message, res2, str3);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ message.getStr(), OUString(str3), res2);
+}
+
+void test::oustringbuffer::Utf32::insertUtf32() {
+ int const str1Len = 3;
+ sal_Unicode const str1[str1Len] = { 'a', 'b', 'c' };
+ static constexpr OUStringLiteral str2 = u"abdc";
+ static constexpr OUStringLiteral str3 = u"ab\U0010FFFFdc";
+ OStringBuffer message;
+ OUStringBuffer buf1(std::u16string_view(str1, str1Len));
+ buf1.insertUtf32(2, 'd');
+ OUString res1(buf1.makeStringAndClear());
+ createMessage(message, res1, str2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ message.getStr(), OUString(str2), res1);
+ OUStringBuffer buf2(str2);
+ buf2.insertUtf32(2, 0x10FFFF);
+ OUString res2(buf2.makeStringAndClear());
+ createMessage(message, res2, str3);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ message.getStr(), OUString(str3), res2);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/process/child_process.cxx b/sal/qa/rtl/process/child_process.cxx
new file mode 100644
index 000000000..d5039b059
--- /dev/null
+++ b/sal/qa/rtl/process/child_process.cxx
@@ -0,0 +1,60 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdio.h>
+#include "sal/main.h"
+#include <rtl/process.h>
+#include <rtl_Process_Const.h>
+
+// ----------------------------------- Main -----------------------------------
+SAL_IMPLEMENT_MAIN_WITH_ARGS(, argv)
+{
+ printf("# %s is called.\n", argv[0]);
+
+ sal_Int32 nCount = rtl_getAppCommandArgCount();
+ if ( nCount != 4 )
+ {
+ printf(
+ "# not enough arguments found, need 4 found %ld.\n",
+ sal::static_int_cast< long >(nCount));
+ return 0;
+ }
+
+ OUString suArg[4];
+ for( sal_Int32 i = 0 ; i < nCount ; i ++ )
+ {
+ rtl_getAppCommandArg( i , &(suArg[i].pData) );
+ OString aString;
+ aString = OUStringToOString( suArg[i], RTL_TEXTENCODING_ASCII_US );
+ printf(
+ "# Parameter[%ld] is %s\n", sal::static_int_cast< long >(i),
+ aString.getStr());
+ }
+
+ if ( suArg[0] != suParam0 ||
+ suArg[1] != suParam1 ||
+ suArg[2] != suParam2 ||
+ suArg[3] != suParam3 )
+ {
+ return 0;
+ }
+ return 2;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/process/child_process_id.cxx b/sal/qa/rtl/process/child_process_id.cxx
new file mode 100644
index 000000000..077f5c668
--- /dev/null
+++ b/sal/qa/rtl/process/child_process_id.cxx
@@ -0,0 +1,54 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdio.h>
+#include "sal/main.h"
+#include <rtl/process.h>
+#include <rtl_Process_Const.h>
+
+void printUuid(sal_uInt8* pNode)
+{
+ for (sal_Int32 i1 = 0; i1 < 4; i1++)
+ {
+ for (sal_Int32 i2 = 0; i2 < 4; i2++)
+ {
+ sal_uInt8 nValue = pNode[i1 * 4 + i2];
+ if (nValue < 16)
+ {
+ printf("0");
+ }
+ printf("%02x", nValue);
+ }
+ if (i1 == 3)
+ break;
+ //printf( "-" );
+ }
+}
+
+// ----------------------------------- Main -----------------------------------
+
+SAL_IMPLEMENT_MAIN()
+{
+ sal_uInt8 pTargetUUID[16];
+ rtl_getGlobalProcessId(pTargetUUID);
+ printUuid(pTargetUUID);
+ return 1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/process/rtl_Process.cxx b/sal/qa/rtl/process/rtl_Process.cxx
new file mode 100644
index 000000000..5d4f3e5b5
--- /dev/null
+++ b/sal/qa/rtl/process/rtl_Process.cxx
@@ -0,0 +1,258 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sal/types.h>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <rtl/process.h>
+#include <osl/process.h>
+#include <osl/module.hxx>
+
+#include "rtl_Process_Const.h"
+
+using namespace osl;
+
+/** print a UNI_CODE String. And also print some comments of the string.
+*/
+static void printUString( const OUString & str, const char * msg )
+{
+ if ( msg != nullptr )
+ {
+ printf("#%s #printUString_u# ", msg );
+ }
+ OString aString = OUStringToOString( str, RTL_TEXTENCODING_ASCII_US );
+ printf("%s\n", aString.getStr( ) );
+}
+
+static OUString getModulePath()
+{
+ OUString suDirPath;
+ ::osl::Module::getUrlFromAddress(
+ reinterpret_cast< oslGenericFunction >(getModulePath), suDirPath );
+
+ printUString(suDirPath, "modulePath:");
+ suDirPath = suDirPath.copy( 0, suDirPath.lastIndexOf('/') );
+ suDirPath = OUString::Concat(suDirPath.subView( 0, suDirPath.lastIndexOf('/') + 1)) + "bin";
+ return suDirPath;
+}
+
+namespace rtl_Process
+{
+class getAppCommandArg : public CppUnit::TestFixture
+{
+public:
+ void getAppCommandArg_001()
+ {
+#if defined(_WIN32)
+ static const OUStringLiteral EXECUTABLE_NAME(u"child_process.exe");
+#else
+ static const OUStringLiteral EXECUTABLE_NAME(u"child_process");
+#endif
+ OUString suCWD = getModulePath();
+ // OUString suCWD2 = getExecutableDirectory();
+
+ printUString(suCWD, "path to the current module");
+ // printUString(suCWD2, "suCWD2");
+
+ oslProcess hProcess = nullptr;
+
+ const int nParameterCount = 4;
+ rtl_uString* pParameters[ nParameterCount ];
+
+ pParameters[0] = suParam0.pData;
+ pParameters[1] = suParam1.pData;
+ pParameters[2] = suParam2.pData;
+ pParameters[3] = suParam3.pData;
+
+ OUString suFileURL = suCWD + "/" + EXECUTABLE_NAME;
+
+ oslProcessError osl_error = osl_executeProcess(
+ suFileURL.pData,
+ pParameters,
+ nParameterCount,
+ osl_Process_WAIT,
+ nullptr, /* osl_getCurrentSecurity() */
+ suCWD.pData,
+ nullptr,
+ 0,
+ &hProcess );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE
+ (
+ "osl_createProcess failed",
+ osl_Process_E_None, osl_error
+ );
+ //we could get return value only after the process terminated
+ osl_joinProcess(hProcess);
+ // CPPUNIT_ASSERT_MESSAGE
+ // (
+ // "osl_joinProcess returned with failure",
+ // osl_Process_E_None == osl_error
+ // );
+ std::unique_ptr<oslProcessInfo> pInfo( new oslProcessInfo );
+ //please pay attention to initial the Size to sizeof(oslProcessInfo), or else
+ //you will get unknown error when call osl_getProcessInfo
+ pInfo->Size = sizeof(oslProcessInfo);
+ osl_error = osl_getProcessInfo( hProcess, osl_Process_EXITCODE, pInfo.get() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE
+ (
+ "osl_getProcessInfo returned with failure",
+ osl_Process_E_None, osl_error
+ );
+
+ printf("the exit code is %" SAL_PRIuUINT32 ".\n", pInfo->Code );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("rtl_getAppCommandArg or rtl_getAppCommandArgCount error.", static_cast<oslProcessExitCode>(2), pInfo->Code);
+ }
+
+ CPPUNIT_TEST_SUITE(getAppCommandArg);
+ CPPUNIT_TEST(getAppCommandArg_001);
+ // CPPUNIT_TEST(getAppCommandArg_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getAppCommandArg
+
+/************************************************************************
+ * For diagnostics( from sal/test/testuuid.cxx )
+ ************************************************************************/
+static void printUuid( const sal_uInt8 *pNode )
+{
+ printf("# UUID is: ");
+ for( sal_Int32 i1 = 0 ; i1 < 4 ; i1++ )
+ {
+ for( sal_Int32 i2 = 0 ; i2 < 4 ; i2++ )
+ {
+ sal_uInt8 nValue = pNode[i1*4 +i2];
+ if (nValue < 16)
+ {
+ printf( "0");
+ }
+ printf( "%02x" ,nValue );
+ }
+ if( i1 == 3 )
+ break;
+ printf( "-" );
+ }
+ printf("\n");
+}
+
+/**************************************************************************
+ * output UUID to a string
+ **************************************************************************/
+static void printUuidtoBuffer( const sal_uInt8 *pNode, char * pBuffer )
+{
+ sal_Int8 nPtr = 0;
+ for( sal_Int32 i1 = 0 ; i1 < 16 ; i1++ )
+ {
+ sal_uInt8 nValue = pNode[i1];
+ if (nValue < 16)
+ {
+ SAL_WNODEPRECATED_DECLARATIONS_PUSH // sprintf (macOS 13 SDK)
+ sprintf( pBuffer + nPtr, "0");
+ SAL_WNODEPRECATED_DECLARATIONS_POP
+ nPtr++;
+ }
+ SAL_WNODEPRECATED_DECLARATIONS_PUSH // sprintf (macOS 13 SDK)
+ sprintf( pBuffer + nPtr, "%02x", nValue );
+ SAL_WNODEPRECATED_DECLARATIONS_POP
+ nPtr += 2 ;
+ }
+}
+
+class getGlobalProcessId : public CppUnit::TestFixture
+{
+public:
+ //gets a 16-byte fixed size identifier which is guaranteed not to change during the current process.
+ void getGlobalProcessId_001()
+ {
+ sal_uInt8 pTargetUUID1[16];
+ sal_uInt8 pTargetUUID2[16];
+ rtl_getGlobalProcessId( pTargetUUID1 );
+ rtl_getGlobalProcessId( pTargetUUID2 );
+ CPPUNIT_ASSERT_MESSAGE("getGlobalProcessId: got two same ProcessIds.", !memcmp( pTargetUUID1 , pTargetUUID2 , 16 ) );
+ }
+ //different processes different pids
+ void getGlobalProcessId_002()
+ {
+#if defined(_WIN32)
+ static const OUStringLiteral EXEC_NAME(u"child_process_id.exe");
+#else
+ static const OUStringLiteral EXEC_NAME(u"child_process_id");
+#endif
+ sal_uInt8 pTargetUUID1[16];
+ rtl_getGlobalProcessId( pTargetUUID1 );
+ printUuid( pTargetUUID1 );
+ char pUUID1[32];
+ printUuidtoBuffer( pTargetUUID1, pUUID1 );
+ printf("# UUID to String is %s\n", pUUID1);
+
+ OUString suCWD = getModulePath();
+ oslProcess hProcess = nullptr;
+ OUString suFileURL = suCWD + "/" + EXEC_NAME;
+ oslFileHandle* pChildOutputRead = new oslFileHandle();
+ oslProcessError osl_error = osl_executeProcess_WithRedirectedIO(
+ suFileURL.pData,
+ nullptr,
+ 0,
+ osl_Process_WAIT,
+ nullptr,
+ suCWD.pData,
+ nullptr,
+ 0,
+ &hProcess,
+ nullptr,
+ pChildOutputRead,
+ nullptr);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE
+ (
+ "osl_createProcess failed",
+ osl_Process_E_None, osl_error
+ );
+ //we could get return value only after the process terminated
+ osl_joinProcess(hProcess);
+
+ char pUUID2[33] {};
+ sal_uInt64 nRead = 0;
+ osl_readFile( *pChildOutputRead, pUUID2, 32, &nRead );
+ printf("read buffer is %s, nRead is %" SAL_PRIdINT64 "\n", pUUID2, nRead );
+ OUString suUUID2 = OUString::createFromAscii( pUUID2 );
+ CPPUNIT_ASSERT_MESSAGE("getGlobalProcessId: got two same ProcessIds.", !suUUID2.equalsAsciiL( pUUID1, 32) );
+ }
+
+ CPPUNIT_TEST_SUITE(getGlobalProcessId);
+ CPPUNIT_TEST(getGlobalProcessId_001);
+ CPPUNIT_TEST(getGlobalProcessId_002);
+ CPPUNIT_TEST_SUITE_END();
+
+}; // class getGlobalProcessId
+
+} // namespace rtl_Process
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_Process::getAppCommandArg, "rtl_Process");
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_Process::getGlobalProcessId, "rtl_Process");
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/process/rtl_Process_Const.h b/sal/qa/rtl/process/rtl_Process_Const.h
new file mode 100644
index 000000000..aab40ff9a
--- /dev/null
+++ b/sal/qa/rtl/process/rtl_Process_Const.h
@@ -0,0 +1,40 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SAL_QA_RTL_PROCESS_RTL_PROCESS_CONST_H
+#define INCLUDED_SAL_QA_RTL_PROCESS_RTL_PROCESS_CONST_H
+
+#include <rtl/ustring.hxx>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OUString suParam0("-join");
+OUString suParam1("-with");
+OUString suParam2("-child");
+OUString suParam3("-process");
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTL_PROCESS_CONST_H*/
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/random/random.txt b/sal/qa/rtl/random/random.txt
new file mode 100644
index 000000000..c5546df9b
--- /dev/null
+++ b/sal/qa/rtl/random/random.txt
@@ -0,0 +1,22 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+rtl_random.createPool.createPool_001
+rtl_random.destroyPool.destroyPool_001
+rtl_random.addBytes.addBytes_001
+rtl_random.getBytes.getBytes_001
+
diff --git a/sal/qa/rtl/random/rtl_random.cxx b/sal/qa/rtl/random/rtl_random.cxx
new file mode 100644
index 000000000..4987b5a0c
--- /dev/null
+++ b/sal/qa/rtl/random/rtl_random.cxx
@@ -0,0 +1,363 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <algorithm>
+
+#include <sal/types.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <rtl/random.h>
+
+#include <string.h>
+
+namespace rtl_random
+{
+
+class createPool : public CppUnit::TestFixture
+{
+public:
+ // insert your test code here.
+ // this is only demonstration code
+ void createPool_001()
+ {
+ // this is demonstration code
+
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ // LLA: seems to be that another test is not possible for createPool()
+ CPPUNIT_ASSERT_MESSAGE("create failed", aPool != nullptr);
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(createPool);
+ CPPUNIT_TEST(createPool_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class createPool
+
+class destroyPool : public CppUnit::TestFixture
+{
+public:
+ // insert your test code here.
+ void destroyPool_000()
+ {
+ // GPF, if failed
+ rtl_random_destroyPool(nullptr);
+ }
+
+ void destroyPool_001()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ // LLA: seems to be that another test is not possible for createPool()
+ CPPUNIT_ASSERT_MESSAGE("create failed", aPool != nullptr);
+
+ rtl_random_destroyPool(aPool);
+ }
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(destroyPool);
+ CPPUNIT_TEST(destroyPool_000);
+ CPPUNIT_TEST(destroyPool_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class destroyPool
+
+class addBytes : public CppUnit::TestFixture
+{
+public:
+ // insert your test code here.
+ // this is only demonstration code
+ void addBytes_000()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ sal_uInt32 nBufLen = 4;
+ std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] );
+ memset(pBuffer.get(), 0, nBufLen);
+
+ rtlRandomError aError = rtl_random_addBytes(nullptr, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError);
+
+ /* rtlRandomError */ aError = rtl_random_addBytes(aPool, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError);
+
+ /* rtlRandomError */ aError = rtl_random_addBytes(aPool, pBuffer.get(), nBufLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError);
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ void addBytes_001()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ sal_uInt32 nBufLen = 4;
+ std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] );
+
+ memset(pBuffer.get(), 0, nBufLen);
+
+ rtl_random_addBytes(aPool, pBuffer.get(), nBufLen);
+
+ printf("%2x %2x %2x %2x\n", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3]);
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(addBytes);
+ CPPUNIT_TEST(addBytes_000);
+ CPPUNIT_TEST(addBytes_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class addBytes
+
+namespace {
+
+class Statistics
+{
+ int m_nDispensation[256];
+
+ int m_nMin;
+ int m_nMax;
+ int m_nAverage;
+ int m_nMinDeviation;
+ int m_nMaxDeviation;
+
+public:
+ void clearDispensation()
+ {
+ for (int i = 0;i < 256;++i) // clear array
+ {
+ m_nDispensation[i] = 0;
+ }
+ }
+ Statistics()
+ : m_nMin(0)
+ , m_nMax(0)
+ , m_nAverage(0)
+ , m_nMinDeviation(0)
+ , m_nMaxDeviation(0)
+ {
+ clearDispensation();
+ }
+
+ void addValue(sal_uInt8 _nIndex, sal_Int32 _nValue)
+ {
+ m_nDispensation[_nIndex] += _nValue;
+ }
+
+ void build(sal_Int32 _nCountMax)
+ {
+ m_nMin = _nCountMax;
+ m_nMax = 0;
+
+ m_nAverage = _nCountMax / 256;
+
+ m_nMinDeviation = _nCountMax;
+ m_nMaxDeviation = 0;
+
+ for (int i = 0;i < 256;++i) // show dispensation
+ {
+ m_nMin = std::min(m_nMin, m_nDispensation[i]);
+ m_nMax = std::max(m_nMax, m_nDispensation[i]);
+
+ m_nMinDeviation = std::min(m_nMinDeviation, abs(m_nAverage - m_nDispensation[i]));
+ m_nMaxDeviation = std::max(m_nMaxDeviation, abs(m_nAverage - m_nDispensation[i]));
+ }
+ }
+
+ void print()
+ {
+ // LLA: these are only info values
+ printf("\nSome statistics\n");
+ printf("Min: %d\n", m_nMin);
+ printf("Max: %d\n", m_nMax);
+ printf("Average: %d\n", m_nAverage);
+ printf("Min abs deviation: %d\n", m_nMinDeviation);
+ printf("Max abs deviation: %d\n", m_nMaxDeviation);
+ }
+
+ sal_Int32 getAverage() const {return m_nAverage;}
+ sal_Int32 getMaxDeviation() const {return m_nMaxDeviation;}
+
+};
+
+}
+
+class getBytes : public CppUnit::TestFixture
+{
+public:
+ // insert your test code here.
+ void getBytes_000()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ sal_uInt32 nBufLen = 4;
+ std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] );
+ memset(pBuffer.get(), 0, nBufLen);
+
+ rtlRandomError aError = rtl_random_getBytes(nullptr, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError);
+
+ /* rtlRandomError */ aError = rtl_random_getBytes(aPool, nullptr, 0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_Argument, aError);
+
+ /* rtlRandomError */ aError = rtl_random_getBytes(aPool, pBuffer.get(), nBufLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError);
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ void getBytes_001()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ sal_uInt32 nBufLen = 4;
+ std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] );
+ memset(pBuffer.get(), 0, nBufLen);
+
+ rtlRandomError aError = rtl_random_getBytes(aPool, pBuffer.get(), nBufLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError);
+
+ printf("%2x %2x %2x %2x\n", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3]);
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ void getBytes_002()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ sal_uInt32 nBufLen = 4;
+ std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen << 1 ] );
+ memset(pBuffer.get(), 0, nBufLen << 1);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[4]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[5]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[6]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", sal_uInt8(0), pBuffer[7]);
+
+ rtlRandomError aError = rtl_random_getBytes(aPool, pBuffer.get(), nBufLen);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("wrong parameter", rtl_Random_E_None, aError);
+
+ printf("%2x %2x %2x %2x %2x %2x %2x %2x\n", pBuffer[0], pBuffer[1], pBuffer[2], pBuffer[3], pBuffer[4], pBuffer[5], pBuffer[6], pBuffer[7]);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[4]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[5]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[6]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("internal memory overwrite", sal_uInt8(0), pBuffer[7]);
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ void getBytes_003()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ sal_uInt32 nBufLen = 1;
+ std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] );
+ memset(pBuffer.get(), 0, nBufLen);
+
+ Statistics aStat;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", static_cast<sal_uInt8>(0), pBuffer[0]);
+
+ int nCount = 0;
+
+ int nCountMax = 1000000;
+ for(nCount = 0;nCount < nCountMax; ++nCount) // run 100000000 through getBytes(...)
+ {
+ /* rtlRandomError aError = */ rtl_random_getBytes(aPool, pBuffer.get(), nBufLen);
+ /* CPPUNIT_ASSERT_MESSAGE("wrong parameter", aError == rtl_Random_E_None); */
+
+ aStat.addValue(pBuffer[0], 1);
+ }
+
+ aStat.build(nCountMax);
+ aStat.print();
+
+ CPPUNIT_ASSERT_MESSAGE("deviation should be less average", aStat.getMaxDeviation() < aStat.getAverage());
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ void getBytes_003_1()
+ {
+ rtlRandomPool aPool = rtl_random_createPool();
+
+ sal_uInt32 nBufLen = 256;
+ std::unique_ptr<sal_uInt8[]> pBuffer( new sal_uInt8[ nBufLen ] );
+ memset(pBuffer.get(), 0, nBufLen);
+
+ Statistics aStat;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("memset failed", static_cast<sal_uInt8>(0), pBuffer[0]);
+
+ int nCount = 0;
+
+ int nCountMax = 10000;
+ for(nCount = 0;nCount < nCountMax; ++nCount) // run 100000000 through getBytes(...)
+ {
+ /* rtlRandomError aError = */ rtl_random_getBytes(aPool, pBuffer.get(), nBufLen);
+ // CPPUNIT_ASSERT_MESSAGE("wrong parameter", aError == rtl_Random_E_None);
+
+ for (sal_uInt32 i=0;i<nBufLen;++i)
+ aStat.addValue(pBuffer[i], 1);
+ }
+
+ aStat.build(nCountMax * nBufLen);
+ aStat.print();
+
+ CPPUNIT_ASSERT_MESSAGE("deviation should be less average", aStat.getMaxDeviation() < aStat.getAverage());
+
+ rtl_random_destroyPool(aPool);
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(getBytes);
+ CPPUNIT_TEST(getBytes_000);
+ CPPUNIT_TEST(getBytes_001);
+ CPPUNIT_TEST(getBytes_002);
+ CPPUNIT_TEST(getBytes_003);
+ CPPUNIT_TEST(getBytes_003_1);
+ CPPUNIT_TEST_SUITE_END();
+}; // class getBytes
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::createPool);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::destroyPool);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::addBytes);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_random::getBytes);
+} // namespace rtl_random
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/ref/rtl_ref.cxx b/sal/qa/rtl/ref/rtl_ref.cxx
new file mode 100644
index 000000000..2bf7c9803
--- /dev/null
+++ b/sal/qa/rtl/ref/rtl_ref.cxx
@@ -0,0 +1,115 @@
+/* -*- 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/.
+ */
+
+#include <rtl/ref.hxx>
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+namespace rtl_ref
+{
+
+namespace {
+
+class MoveTestClass
+{
+private:
+ bool m_bIncFlag;
+ long m_nRef;
+public:
+ MoveTestClass(): m_bIncFlag(false), m_nRef(0) { }
+
+ // There should never be more than two references to this class as it
+ // is used as a test class for move functions. One reference being the
+ // original reference and the second being the test reference
+ void acquire()
+ {
+ if(m_bIncFlag)
+ {
+ ++m_nRef;
+ m_bIncFlag = false;
+ }
+ else
+ CPPUNIT_FAIL("RC was incremented when in should not have been");
+ }
+
+ void release() { --m_nRef; }
+
+ long use_count() { return m_nRef; }
+
+ void set_inc_flag() { m_bIncFlag = true; }
+};
+
+}
+
+static rtl::Reference< MoveTestClass > get_reference( MoveTestClass* pcTestClass )
+{
+ // constructor will increment the reference count
+ pcTestClass->set_inc_flag();
+ rtl::Reference< MoveTestClass > tmp(pcTestClass);
+ return tmp;
+}
+
+class TestReferenceRefCounting : public CppUnit::TestFixture
+{
+ void testMove()
+ {
+ MoveTestClass cTestClass;
+
+ // constructor will increment the reference count
+ cTestClass.set_inc_flag();
+ rtl::Reference< MoveTestClass > test1( &cTestClass );
+
+ // move should not increment the reference count
+ rtl::Reference< MoveTestClass > test2( std::move(test1) );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("test2.use_count() == 1",
+ static_cast<long>(1), test2->use_count());
+
+ // test1 now contains a null pointer
+ CPPUNIT_ASSERT_MESSAGE("!test1.is()",
+ !test1.is()); // NOLINT(bugprone-use-after-move)
+
+ // function return should move the reference
+ test2 = get_reference( &cTestClass );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("test2.use_count() == 1",
+ static_cast<long>(1), test2->use_count());
+
+ // normal copy
+ test2->set_inc_flag();
+ test1 = test2;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("test2.use_count() == 2",
+ static_cast<long>(2), test2->use_count());
+
+ // use count should decrement
+ test2 = rtl::Reference< MoveTestClass >();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("test1.use_count() == 1",
+ static_cast<long>(1), test1->use_count());
+
+ // move of a null pointer should not cause an error
+ test1 = std::move(test2);
+
+ CPPUNIT_ASSERT_MESSAGE("!test1.is()",
+ !test1.is());
+ CPPUNIT_ASSERT_MESSAGE("!test2.is()",
+ !test2.is()); // NOLINT(bugprone-use-after-move)
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("cTestClass.use_count() == 0",
+ static_cast<long>(0), cTestClass.use_count());
+ }
+
+ CPPUNIT_TEST_SUITE(TestReferenceRefCounting);
+ CPPUNIT_TEST(testMove);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+} // namespace rtl_ref
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_ref::TestReferenceRefCounting);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/compile-oustring.cxx b/sal/qa/rtl/strings/compile-oustring.cxx
new file mode 100644
index 000000000..667a52324
--- /dev/null
+++ b/sal/qa/rtl/strings/compile-oustring.cxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#include <sal/config.h>
+
+#include <rtl/string.h>
+#include <rtl/ustring.hxx>
+
+// expected-note@rtl/ustring.hxx:* 1+ {{}}
+
+void checkExtraIntArgument()
+{
+ // This makes sure that using by mistake RTL_CONSTASCII_STRINGPARAM does not trigger a different
+ // overload, i.e. the second argument to match() in this case is the indexFrom argument,
+ // but with the macro it would contain the length of the string. Therefore
+ // match( RTL_CONSTASCII_STRINGPARAM( "bar" )) would be match( "bar", 3 ), which would be
+ // true when called for OUString( "foobar" ). But this should not happen because of the
+ // &foo[0] trick in the RTL_CONSTASCII_STRINGPARAM macro.
+ // expected-error@+1 {{}}
+ OUString("foobar").match(RTL_CONSTASCII_STRINGPARAM("bar"));
+}
+
+void checkNonconstChar()
+{
+ // check that non-const char[] data do not trigger string literal overloads
+ char test[] = "test";
+ char bar[] = "bar";
+ const char consttest[] = "test";
+ const char constbar[] = "bar";
+ // expected-error@+1 {{}}
+ (void)OUString("footest").replaceAll(test, bar);
+ // expected-error@+1 {{}}
+ (void)OUString("footest").replaceAll(consttest, bar);
+ // expected-error@+1 {{}}
+ (void)OUString("footest").replaceAll(test, constbar);
+ (void)OUString("footest").replaceAll(consttest, constbar);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sal/qa/rtl/strings/nonconstarray.cxx b/sal/qa/rtl/strings/nonconstarray.cxx
new file mode 100644
index 000000000..4b66e4e31
--- /dev/null
+++ b/sal/qa/rtl/strings/nonconstarray.cxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#include <sal/config.h>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+
+namespace
+{
+class Test : public CppUnit::TestFixture
+{
+private:
+ void testOString()
+ {
+ struct S
+ {
+ char a[4];
+ };
+ S s{ "x\0y" };
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), OString(s.a).getLength());
+ // Ideally, the below would work the same as the above. However, the const reference makes
+ // the ConstCharArrayDetector instead of the NonConstCharArrayDetector kick in, so that the
+ // call to OString(r.a) would fire the ConstCharArrayDetector<T>::isValid assert (and in
+ // NDEBUG builds the CPPUNIT_ASSERT_EQUAL would fail with 3 != 1):
+ if ((false))
+ {
+ S const& r = s;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), OString(r.a).getLength());
+ }
+ }
+
+ void testOUStringChar()
+ {
+ struct S
+ {
+ char a[4];
+ };
+ S s{ "x\0y" };
+ // This would fail to compile, as there is no OUString ctor taking a
+ // NonConstCharArrayDetector char array:
+#if 0
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), OUString(s.a).getLength());
+#endif
+ // Ideally, the below would fail to compile the same as the above. However, the const
+ // reference makes the ConstCharArrayDetector instead of the NonConstCharArrayDetector kick
+ // in, so that the call to OUString(r.a) would fire the ConstCharArrayDetector<T>::isValid
+ // assert (and in NDEBUG builds the CPPUNIT_ASSERT_EQUAL would fail with 3 != 1):
+ if ((false))
+ {
+ S const& r = s;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), OUString(r.a).getLength());
+ }
+ }
+
+ void testOUStringChar16t()
+ {
+ struct S
+ {
+ char16_t a[4];
+ };
+ S s{ u"x\0y" };
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), OUString(s.a).getLength());
+ // Ideally, the below would work the same as the above. However, the const reference makes
+ // the ConstCharArrayDetector instead of the NonConstCharArrayDetector kick in, so that the
+ // call to OUString(r.a) would fire the ConstCharArrayDetector<T>::isValid assert (and in
+ // NDEBUG builds the CPPUNIT_ASSERT_EQUAL would fail with 3 != 1)::
+ if ((false))
+ {
+ S const& r = s;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), OUString(r.a).getLength());
+ }
+ }
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testOString);
+ CPPUNIT_TEST(testOUStringChar);
+ CPPUNIT_TEST(testOUStringChar16t);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sal/qa/rtl/strings/test_ostring.cxx b/sal/qa/rtl/strings/test_ostring.cxx
new file mode 100644
index 000000000..b4fb201ca
--- /dev/null
+++ b/sal/qa/rtl/strings/test_ostring.cxx
@@ -0,0 +1,123 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/string.hxx>
+
+namespace {
+
+class Test: public CppUnit::TestFixture {
+private:
+ void testStartsWithIgnoreAsciiCase();
+ void testCompareTo();
+ void testUtf8StringLiterals();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testStartsWithIgnoreAsciiCase);
+ CPPUNIT_TEST(testCompareTo);
+ CPPUNIT_TEST(testUtf8StringLiterals);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::testStartsWithIgnoreAsciiCase() {
+ {
+ OString r;
+ CPPUNIT_ASSERT(OString().startsWithIgnoreAsciiCase(std::string_view(), &r));
+ CPPUNIT_ASSERT(r.isEmpty());
+ }
+ {
+ OString r;
+ CPPUNIT_ASSERT(OString("foo").startsWithIgnoreAsciiCase(std::string_view(), &r));
+ CPPUNIT_ASSERT_EQUAL(OString("foo"), r);
+ }
+ {
+ OString r;
+ CPPUNIT_ASSERT(
+ OString("foo").startsWithIgnoreAsciiCase("F", &r));
+ CPPUNIT_ASSERT_EQUAL(OString("oo"), r);
+ }
+ {
+ OString r("other");
+ CPPUNIT_ASSERT(
+ !OString("foo").startsWithIgnoreAsciiCase("bar", &r));
+ CPPUNIT_ASSERT_EQUAL(OString("other"), r);
+ }
+ {
+ OString r("other");
+ CPPUNIT_ASSERT(
+ !OString("foo").startsWithIgnoreAsciiCase("foobar", &r));
+ CPPUNIT_ASSERT_EQUAL(OString("other"), r);
+ }
+
+ {
+ OString r;
+ CPPUNIT_ASSERT(OString().startsWithIgnoreAsciiCase("", &r));
+ CPPUNIT_ASSERT(r.isEmpty());
+ }
+ {
+ OString r;
+ CPPUNIT_ASSERT(OString("foo").startsWithIgnoreAsciiCase("", &r));
+ CPPUNIT_ASSERT_EQUAL(OString("foo"), r);
+ }
+ {
+ OString r;
+ CPPUNIT_ASSERT(
+ OString("foo").startsWithIgnoreAsciiCase("F", &r));
+ CPPUNIT_ASSERT_EQUAL(OString("oo"), r);
+ }
+ {
+ OString r("other");
+ CPPUNIT_ASSERT(
+ !OString("foo").startsWithIgnoreAsciiCase("bar", &r));
+ CPPUNIT_ASSERT_EQUAL(OString("other"), r);
+ }
+ {
+ OString r("other");
+ CPPUNIT_ASSERT(
+ !OString("foo").startsWithIgnoreAsciiCase("foobar", &r));
+ CPPUNIT_ASSERT_EQUAL(OString("other"), r);
+ }
+}
+
+void Test::testCompareTo()
+{
+ // test that embedded NUL does not stop the compare
+ char str1[2] = { '\0', 'x' };
+ char str2[2] = { '\0', 'y' };
+
+ OString s1(str1, 2);
+ OString s2(str2, 2);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), s1.compareTo(s1));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), s2.compareTo(s2));
+ CPPUNIT_ASSERT(s1.compareTo(s2) < 0);
+ CPPUNIT_ASSERT(s2.compareTo(s1) > 0);
+ CPPUNIT_ASSERT(s1.compareTo(OString(s2 + "y")) < 0);
+ CPPUNIT_ASSERT(s2.compareTo(OString(s1 + "x")) > 0);
+ CPPUNIT_ASSERT(OString(s1 + "x").compareTo(s2) < 0);
+ CPPUNIT_ASSERT(OString(s2 + "y").compareTo(s1) > 0);
+}
+
+void Test::testUtf8StringLiterals()
+{
+ const OString sIn(u8"ßa");
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), sIn.getLength());
+ CPPUNIT_ASSERT_EQUAL(195, int(static_cast<unsigned char>(sIn[0])));
+ CPPUNIT_ASSERT_EQUAL(159, int(static_cast<unsigned char>(sIn[1])));
+ CPPUNIT_ASSERT_EQUAL(97, int(static_cast<unsigned char>(sIn[2])));
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_ostring_concat.cxx b/sal/qa/rtl/strings/test_ostring_concat.cxx
new file mode 100644
index 000000000..853f97564
--- /dev/null
+++ b/sal/qa/rtl/strings/test_ostring_concat.cxx
@@ -0,0 +1,206 @@
+/* -*- 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/.
+ */
+
+// activate support for detecting errors instead of getting compile errors
+#define RTL_STRING_UNITTEST_CONCAT
+
+#include <sal/types.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <string>
+#include <typeinfo>
+
+bool rtl_string_unittest_invalid_concat = false;
+
+using namespace rtl;
+
+namespace CppUnit
+{
+template<> struct assertion_traits<std::type_info>
+{
+ static bool equal(std::type_info const & x, std::type_info const & y) { return x == y; }
+
+ static std::string toString(std::type_info const & x) { return x.name(); }
+};
+} // namespace
+
+namespace test::ostring {
+
+class StringConcat : public CppUnit::TestFixture
+{
+private:
+ void checkConcat();
+ void checkEnsureCapacity();
+ void checkAppend();
+ void checkInvalid();
+
+CPPUNIT_TEST_SUITE(StringConcat);
+CPPUNIT_TEST(checkConcat);
+CPPUNIT_TEST(checkEnsureCapacity);
+CPPUNIT_TEST(checkAppend);
+CPPUNIT_TEST(checkInvalid);
+CPPUNIT_TEST_SUITE_END();
+};
+
+void test::ostring::StringConcat::checkConcat()
+{
+// All the extra () are to protect commas against being treated as separators of macro arguments.
+ CPPUNIT_ASSERT_EQUAL( OString(), OString(OString() + OString()));
+ CPPUNIT_ASSERT_EQUAL( OString( "foobar" ), OString( OString( "foo" ) + OString( "bar" )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, OString > )), typeid( OString( "foo" ) + OString( "bar" )));
+ CPPUNIT_ASSERT_EQUAL( OString( "foobar" ), OString( OString( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, const char[ 4 ] > )), typeid( OString( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OString( "foobarbaz" ), OString( OString( "foo" ) + "bar" + "baz" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringConcat< OString, const char[ 4 ] >, const char[ 4 ] > )), typeid( OString( "foo" ) + "bar" + "baz" ));
+ CPPUNIT_ASSERT_EQUAL( OString( "foobar" ), OString( OStringBuffer( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringBuffer, const char[ 4 ] > )), typeid( OStringBuffer( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OString( "foobar" ), OString( OStringLiteral( "foo" ) + "bar" ));
+#if defined __GNUC__ && __GNUC__ <= 11 && !defined __clang__
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringLiteral<4>, const char[ 4 ] > )), typeid( OStringLiteral<4>( "foo" ) + "bar" ));
+ // the explicit OStringLiteral<4> template argument in the unevaluated typeid context
+ // is needed by some GCC versions, see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96878>
+ // "Failed class template argument deduction in unevaluated, parenthesized context"
+#else
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringLiteral<4>, const char[ 4 ] > )), typeid( OStringLiteral( "foo" ) + "bar" ));
+#endif
+ CPPUNIT_ASSERT_EQUAL( OString( "foobar" ), OString( OStringLiteral( "foo" ) + static_cast<const char*>("bar") ));
+#if defined __GNUC__ && __GNUC__ <= 11 && !defined __clang__
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringLiteral<4>, const char* > )), typeid( OStringLiteral<4>( "foo" ) + static_cast<const char*>("bar") ));
+ // the explicit OStringLiteral<4> template argument in the unevaluated typeid context
+ // is needed by some GCC versions, see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96878>
+ // "Failed class template argument deduction in unevaluated, parenthesized context"
+#else
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringLiteral<4>, const char* > )), typeid( OStringLiteral( "foo" ) + static_cast<const char*>("bar") ));
+#endif
+ const char d1[] = "xyz";
+ char d2[] = "abc";
+ const char* d3 = d1;
+ char* d4 = d2;
+ CPPUNIT_ASSERT_EQUAL( OString( "fooxyz" ), OString( OString( "foo" ) + d1 ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, const char[ 4 ] > )), typeid( OString( "foo" ) + d1 ));
+ CPPUNIT_ASSERT_EQUAL( OString( "fooabc" ), OString( OString( "foo" ) + d2 ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, char[ 4 ] > )), typeid( OString( "foo" ) + d2 ));
+ CPPUNIT_ASSERT_EQUAL( OString( "fooxyz" ), OString( OString( "foo" ) + d3 ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, const char* > )), typeid( OString( "foo" ) + d3 ));
+ CPPUNIT_ASSERT_EQUAL( OString( "fooabc" ), OString( OString( "foo" ) + d4 ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, char* > )), typeid( OString( "foo" ) + d4 ));
+ CPPUNIT_ASSERT_EQUAL( OString( "fooabc" ), OString( OString( "foo" ) + d4 ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, char* > )), typeid( OString( "foo" ) + d4 ));
+ CPPUNIT_ASSERT_EQUAL( OString( "foobar" ), OString( OString::Concat( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringConcat< OStringConcatMarker, const char[ 4 ] >, const char[ 4 ] > )), typeid( OString::Concat( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OString( "xyzbar" ), OString( OString::Concat( d1 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringConcat< OStringConcatMarker, const char[ 4 ] >, const char[ 4 ] > )), typeid( OString::Concat( d1 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OString( "abcbar" ), OString( OString::Concat( d2 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringConcat< OStringConcatMarker, char[ 4 ] >, const char[ 4 ] > )), typeid( OString::Concat( d2 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OString( "xyzbar" ), OString( OString::Concat( d3 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringConcat< OStringConcatMarker, const char* >, const char[ 4 ] > )), typeid( OString::Concat( d3 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OString( "abcbar" ), OString( OString::Concat( d4 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OStringConcat< OStringConcatMarker, char* >, const char[ 4 ] > )), typeid( OString::Concat( d4 ) + "bar" ));
+
+ CPPUNIT_ASSERT_EQUAL( OString( "num10" ), OString( OString( "num" ) + OString::number( 10 )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, OStringNumber< int > > )), typeid( OString( "num" ) + OString::number( 10 )));
+ CPPUNIT_ASSERT_EQUAL( OString( "num10" ), OString( OString( "num" ) + OString::number( 10L )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, OStringNumber< long long > > )), typeid( OString( "num" ) + OString::number( 10L )));
+ CPPUNIT_ASSERT_EQUAL( OString( "num10" ), OString( OString( "num" ) + OString::number( 10ULL )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, OStringNumber< unsigned long long > > )), typeid( OString( "num" ) + OString::number( 10ULL )));
+ CPPUNIT_ASSERT_EQUAL( OString( "num10.5" ), OString( OString( "num" ) + OString::number( 10.5f )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, OStringNumber< float > > )), typeid( OString( "num" ) + OString::number( 10.5f )));
+ CPPUNIT_ASSERT_EQUAL( OString( "num10.5" ), OString( OString( "num" ) + OString::number( 10.5 )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OStringConcat< OString, OStringNumber< double > > )), typeid( OString( "num" ) + OString::number( 10.5 )));
+}
+
+void test::ostring::StringConcat::checkEnsureCapacity()
+{
+ rtl_String* str = nullptr;
+ rtl_string_newFromLiteral( &str, "test", strlen( "test" ), 0 );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length );
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+
+ rtl_String* oldStr = str;
+ rtl_string_ensureCapacity( &str, 4 ); // should be no-op
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length );
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+ CPPUNIT_ASSERT_EQUAL( str, oldStr );
+
+ rtl_string_acquire( oldStr );
+ CPPUNIT_ASSERT_EQUAL( 2, int( str->refCount ));
+ rtl_string_ensureCapacity( &str, 4 );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length );
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+ // a copy was forced because of refcount
+ CPPUNIT_ASSERT( oldStr != str );
+ CPPUNIT_ASSERT_EQUAL( 0, strcmp( oldStr->buffer, str->buffer ) );
+ CPPUNIT_ASSERT_EQUAL( 1, int( oldStr->refCount ));
+ rtl_string_release( str );
+ str = oldStr;
+
+ rtl_string_acquire( oldStr );
+ rtl_string_ensureCapacity( &str, 1024 );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length ); // size is still 4
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+ CPPUNIT_ASSERT( oldStr != str );
+ CPPUNIT_ASSERT_EQUAL( 0, strcmp( oldStr->buffer, str->buffer ) );
+ CPPUNIT_ASSERT_EQUAL( 1, int( oldStr->refCount ));
+ strcpy( str->buffer, "01234567890123456789" ); // but there should be extra capacity
+ str->length += 20;
+ rtl_string_release( str );
+ rtl_string_release( oldStr );
+}
+
+void test::ostring::StringConcat::checkAppend()
+{
+ OString str( "foo" );
+ str += OStringLiteral( "bar" ) + "baz";
+ CPPUNIT_ASSERT_EQUAL( OString( "foobarbaz" ), str );
+ OStringBuffer buf( "foo" );
+ buf.append( OStringLiteral( "bar" ) + "baz" );
+ CPPUNIT_ASSERT_EQUAL( OString( "foobarbaz" ), buf.makeStringAndClear());
+}
+
+#define INVALID_CONCAT( expression ) \
+ ( \
+ rtl_string_unittest_invalid_concat = false, \
+ ( void ) OString( expression ), \
+ rtl_string_unittest_invalid_concat )
+
+void test::ostring::StringConcat::checkInvalid()
+{
+ CPPUNIT_ASSERT( !INVALID_CONCAT( OString() + OString()));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OString( "a" ) + OUString( "b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OString( "a" ) + OUStringBuffer( "b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OString( "a" ) + OUStringLiteral( u"b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OString( "a" ) + OUString::Concat( u"b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OString( "a" ) + 1 ));
+ rtl_String* rs = nullptr;
+ rtl_uString* rus = nullptr;
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "b" ) + rs ));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "b" ) + rus ));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OString( "a" ) + OUString::number( 10 )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OString::number( 0 ) + OUString::number( 10 )));
+
+#if 0
+ // Should fail to compile, to avoid use of OStringConcat lvalues that
+ // contain dangling references to temporaries:
+ auto const conc = OStringLiteral("foo") + "bar";
+ (void) OString(conc);
+#endif
+}
+
+} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::ostring::StringConcat);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
new file mode 100644
index 000000000..ec0faec94
--- /dev/null
+++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
@@ -0,0 +1,282 @@
+/* -*- 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/.
+ */
+
+// activate the extra needed ctor
+#define RTL_STRING_UNITTEST
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/string.h>
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+
+bool rtl_string_unittest_const_literal;
+bool rtl_string_unittest_const_literal_function;
+static bool rtl_string_unittest_non_const_literal_function;
+
+namespace test::ostring {
+
+class StringLiterals: public CppUnit::TestFixture
+{
+private:
+ void checkCtors();
+ void checkConstexprCtor();
+ void checkUsage();
+ void checkNonConstUsage();
+ void checkBuffer();
+
+ void testcall( const char str[] );
+
+ static const char bad5[];
+ static char bad6[];
+
+ // Check that OStringLiteral ctor is actually constexpr:
+ static constexpr rtlunittest::OStringLiteral dummy{"dummy"};
+
+CPPUNIT_TEST_SUITE(StringLiterals);
+CPPUNIT_TEST(checkCtors);
+CPPUNIT_TEST(checkConstexprCtor);
+CPPUNIT_TEST(checkUsage);
+CPPUNIT_TEST(checkNonConstUsage);
+CPPUNIT_TEST(checkBuffer);
+CPPUNIT_TEST_SUITE_END();
+};
+
+// reset the flag, call OString ctor with the given argument and return
+// whether the string literal ctor was used
+#define CONST_CTOR_USED( argument ) \
+ ( \
+ rtl_string_unittest_const_literal = false, \
+ ( void ) rtl::OString( argument ), \
+ result_tmp = rtl_string_unittest_const_literal, \
+ rtl_string_unittest_const_literal = false, \
+ ( void ) rtl::OStringBuffer( argument ), \
+ rtl_string_unittest_const_literal && result_tmp )
+
+void test::ostring::StringLiterals::checkCtors()
+{
+ bool result_tmp;
+ CPPUNIT_ASSERT( CONST_CTOR_USED( "test" ));
+ const char good1[] = "test";
+ CPPUNIT_ASSERT( CONST_CTOR_USED( good1 ));
+
+ CPPUNIT_ASSERT( !CONST_CTOR_USED( static_cast<const char*>("test") ));
+ const char* bad1 = good1;
+ CPPUNIT_ASSERT( !CONST_CTOR_USED( bad1 ));
+ char bad2[] = "test";
+ CPPUNIT_ASSERT( !CONST_CTOR_USED( bad2 ));
+ char* bad3 = bad2;
+ CPPUNIT_ASSERT( !CONST_CTOR_USED( bad3 ));
+ const char* bad4[] = { "test1" };
+ CPPUNIT_ASSERT( !CONST_CTOR_USED( bad4[ 0 ] ));
+ testcall( good1 );
+#ifndef _MSC_VER
+ // this is actually not supposed to work (see discussion in stringutils.hxx),
+ // but gcc and clang somehow manage, so keep it used, just in case some other problem
+ // shows up somewhen in the future
+ CPPUNIT_ASSERT( !CONST_CTOR_USED( bad5 )); // size is not known here
+ CPPUNIT_ASSERT( !CONST_CTOR_USED( bad6 ));
+#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 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[ 1 ] ));
+
+// Check that contents are correct and equal to the case when const char* ctor is used.
+ CPPUNIT_ASSERT_EQUAL( rtl::OString( "" ), rtl::OString( static_cast<const char*>("") ) );
+ CPPUNIT_ASSERT_EQUAL( rtl::OString( "ab" ), rtl::OString( static_cast<const char*>("ab") ) );
+
+// Check that contents are correct and equal to the case when RTL_CONSTASCII_STRINGPARAM is used.
+ CPPUNIT_ASSERT_EQUAL( rtl::OString( "" ), rtl::OString( RTL_CONSTASCII_STRINGPARAM( "" )) );
+ CPPUNIT_ASSERT_EQUAL( rtl::OString( "ab" ), rtl::OString( RTL_CONSTASCII_STRINGPARAM( "ab" )) );
+}
+
+const char test::ostring::StringLiterals::bad5[] = "test";
+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
+ (void)str;
+#endif
+}
+
+void test::ostring::StringLiterals::checkConstexprCtor()
+{
+#if __cplusplus >= 202002L
+ static constinit
+#endif
+ rtl::OString s(dummy);
+ CPPUNIT_ASSERT_EQUAL(oslInterlockedCount(0x40000000), s.pData->refCount);
+ // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), s.getLength());
+ CPPUNIT_ASSERT_EQUAL(rtl::OString("dummy"), s);
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<void const *>(dummy.getStr()), static_cast<void const *>(s.getStr()));
+}
+
+void test::ostring::StringLiterals::checkUsage()
+{
+// simply check that all string literal based calls work as expected
+// also check that they really use string literal overload and do not convert to OString
+ rtl::OString foo( "foo" );
+ rtl::OString FoO( "FoO" );
+ rtl::OString foobarfoo( "foobarfoo" );
+ rtl::OString foobar( "foobar" );
+ rtl::OString FooBaRfoo( "FooBaRfoo" );
+ rtl::OString FooBaR( "FooBaR" );
+ rtl::OString bar( "bar" );
+
+ rtl_string_unittest_const_literal = false; // start checking for OString conversions
+ rtl_string_unittest_non_const_literal_function = false; // and check for non-const variants
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = "foo" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( "fOo" ));
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( foobarfoo.match( "bar", 3 ));
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( foobar.match( "foo" ));
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( "bAr", 3 ));
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( "fOo" ));
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( foobar.startsWith( "foo" ));
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( foobar.endsWith( "bar" ));
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+// rtl_string_unittest_const_literal_function = false;
+// CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( "bar" ));
+// CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( bool(foo == "foo") );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( bool("foo" == foo) );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( foo != "bar" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT( "foo" != bar );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ rtl_string_unittest_const_literal_function = false;
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.indexOf( "foo", 1 ) );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+// rtl_string_unittest_const_literal_function = false;
+// CPPUNIT_ASSERT( foobarfoo.lastIndexOf( "foo" ) == 6 );
+// CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function == true );
+ // if this is not true, some of the calls above converted to OString
+ CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
+ // if this is not true, some of the calls above used non-const variants
+ CPPUNIT_ASSERT( !rtl_string_unittest_non_const_literal_function );
+}
+
+void test::ostring::StringLiterals::checkNonConstUsage()
+{
+// check that (non-const) char[] overloads work and do not use const char[] overloads
+ rtl::OString foo( "foo" );
+ rtl::OString FoO( "FoO" );
+ rtl::OString foobarfoo( "foobarfoo" );
+ rtl::OString foobar( "foobar" );
+ rtl::OString FooBaRfoo( "FooBaRfoo" );
+ rtl::OString FooBaR( "FooBaR" );
+ rtl::OString bar( "bar" );
+ char foo_c[] = "foo";
+ char bar_c[] = "bar";
+ char fOo_c[] = "fOo";
+ char bAr_c[] = "bAr";
+
+ rtl_string_unittest_const_literal = false; // start checking for OString conversions
+ rtl_string_unittest_const_literal_function = false; // and check for const variants
+ CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = static_cast<const char*>(foo_c) );
+ CPPUNIT_ASSERT_EQUAL( foo, rtl::OString() = foo_c );
+ CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( static_cast<const char*>(fOo_c) ));
+ CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( fOo_c ));
+ CPPUNIT_ASSERT( foobarfoo.match( static_cast<const char*>(bar_c), 3 ));
+ CPPUNIT_ASSERT( foobarfoo.match( bar_c, 3 ));
+ CPPUNIT_ASSERT( foobar.match( static_cast<const char*>(foo_c) ));
+ CPPUNIT_ASSERT( foobar.match( foo_c ));
+ CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( static_cast<const char*>(bAr_c), 3 ));
+ CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( bAr_c, 3 ));
+ CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( static_cast<const char*>(fOo_c) ));
+ CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( fOo_c ));
+ CPPUNIT_ASSERT( foobar.startsWith( static_cast<const char*>(foo_c) ));
+ CPPUNIT_ASSERT( foobar.startsWith( foo_c ));
+ CPPUNIT_ASSERT( foobar.endsWith( static_cast<const char*>(bar_c) ));
+ CPPUNIT_ASSERT( foobar.endsWith( bar_c ));
+// CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( (const char*)bar_c ));
+// CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( bar_c ));
+ CPPUNIT_ASSERT( bool(foo == static_cast<const char*>(foo_c)) );
+ CPPUNIT_ASSERT( bool(foo == foo_c) );
+ CPPUNIT_ASSERT( bool(static_cast<const char*>(foo_c) == foo) );
+ CPPUNIT_ASSERT( bool(foo_c == foo) );
+ CPPUNIT_ASSERT( foo != static_cast<const char*>(bar_c) );
+ CPPUNIT_ASSERT( foo != bar_c );
+ CPPUNIT_ASSERT( static_cast<const char*>(foo_c) != bar );
+ CPPUNIT_ASSERT( foo_c != bar );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.indexOf( static_cast<const char*>(foo_c), 1 ) );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.indexOf( foo_c, 1 ) );
+// CPPUNIT_ASSERT( foobarfoo.lastIndexOf( (const char*)foo_c ) == 6 );
+// CPPUNIT_ASSERT( foobarfoo.lastIndexOf( foo_c ) == 6 );
+ // if this is not true, some of the calls above used const variants
+ CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
+ CPPUNIT_ASSERT( !rtl_string_unittest_const_literal_function );
+}
+
+void test::ostring::StringLiterals::checkBuffer()
+{
+ rtl::OStringBuffer buf;
+ rtl_string_unittest_const_literal_function = false;
+ buf.append( "foo" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ CPPUNIT_ASSERT_EQUAL( rtl::OString( "foo" ), buf.toString());
+ rtl_string_unittest_const_literal_function = false;
+ buf.append( "bar" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ CPPUNIT_ASSERT_EQUAL( rtl::OString( "foobar" ), buf.toString());
+ rtl_string_unittest_const_literal_function = false;
+ buf.insert( 3, "baz" );
+ CPPUNIT_ASSERT( rtl_string_unittest_const_literal_function );
+ CPPUNIT_ASSERT_EQUAL( rtl::OString( "foobazbar" ), buf.toString());
+
+ rtl::OString foobazbard( "foobazbard" );
+ rtl::OString foodbazbard( "foodbazbard" );
+ rtl_string_unittest_const_literal = false; // start checking for OString conversions
+ rtl_string_unittest_const_literal_function = false; // and check for const variants
+ char d[] = "d";
+ CPPUNIT_ASSERT_EQUAL( foobazbard, buf.append( d ).toString());
+ CPPUNIT_ASSERT_EQUAL( foodbazbard, buf.insert( 3, d ).toString() );
+ CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
+ CPPUNIT_ASSERT( !rtl_string_unittest_const_literal_function );
+}
+
+#undef CONST_CTOR_USED
+
+} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::ostring::StringLiterals);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_ostringbuffer.cxx b/sal/qa/rtl/strings/test_ostringbuffer.cxx
new file mode 100644
index 000000000..292e24310
--- /dev/null
+++ b/sal/qa/rtl/strings/test_ostringbuffer.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/stringutils.hxx>
+#include <sal/types.h>
+
+namespace
+{
+class Test : public CppUnit::TestFixture
+{
+private:
+ void testStringView()
+ {
+ OStringBuffer b("foobar");
+ b = std::string_view("abc").substr(
+ 0, 2); // avoid the string_view accidentally being NUL-terminated
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), b.getLength());
+ CPPUNIT_ASSERT_EQUAL('a', b.getStr()[0]);
+ CPPUNIT_ASSERT_EQUAL('b', b.getStr()[1]);
+ CPPUNIT_ASSERT_EQUAL('\0', b.getStr()[2]);
+ }
+
+ void testOStringChar()
+ {
+ OStringBuffer b("foobar");
+ b = OStringChar('a');
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), b.getLength());
+ CPPUNIT_ASSERT_EQUAL('a', b.getStr()[0]);
+ CPPUNIT_ASSERT_EQUAL('\0', b.getStr()[1]);
+ }
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testStringView);
+ CPPUNIT_TEST(testOStringChar);
+ CPPUNIT_TEST_SUITE_END();
+};
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sal/qa/rtl/strings/test_oustring_compare.cxx b/sal/qa/rtl/strings/test_oustring_compare.cxx
new file mode 100644
index 000000000..e55d4d3d9
--- /dev/null
+++ b/sal/qa/rtl/strings/test_oustring_compare.cxx
@@ -0,0 +1,97 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/string.h>
+#include <rtl/ustring.hxx>
+
+namespace test::oustring {
+
+class Compare: public CppUnit::TestFixture
+{
+private:
+ void equalsIgnoreAsciiCaseAscii();
+ void compareToIgnoreAsciiCase();
+ void compareTo();
+
+CPPUNIT_TEST_SUITE(Compare);
+CPPUNIT_TEST(equalsIgnoreAsciiCaseAscii);
+CPPUNIT_TEST(compareToIgnoreAsciiCase);
+CPPUNIT_TEST(compareTo);
+CPPUNIT_TEST_SUITE_END();
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::Compare);
+
+void test::oustring::Compare::equalsIgnoreAsciiCaseAscii()
+{
+ const char* const abc = "abc";
+ const char* const abcd = "abcd";
+ const char* const empty = "";
+ CPPUNIT_ASSERT(!OUString().equalsIgnoreAsciiCaseAscii(abc));
+ CPPUNIT_ASSERT(!OUString().equalsIgnoreAsciiCaseAsciiL(abc,3));
+ CPPUNIT_ASSERT(!OUString("abc").
+ equalsIgnoreAsciiCaseAscii(empty));
+ CPPUNIT_ASSERT(!OUString("abc").
+ equalsIgnoreAsciiCaseAsciiL(empty,0));
+
+ CPPUNIT_ASSERT(OUString("abc").
+ equalsIgnoreAsciiCaseAscii(abc));
+ CPPUNIT_ASSERT(!OUString("abcd").
+ equalsIgnoreAsciiCaseAscii(abc));
+ CPPUNIT_ASSERT(!OUString("abc").
+ equalsIgnoreAsciiCaseAscii(abcd));
+}
+
+void test::oustring::Compare::compareToIgnoreAsciiCase()
+{
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(0),
+ OUString("abc").compareToIgnoreAsciiCase(u"ABC"));
+ CPPUNIT_ASSERT(
+ OUString("ABC").compareToIgnoreAsciiCase(u"abcdef")
+ < 0);
+ CPPUNIT_ASSERT(
+ OUString("A").compareToIgnoreAsciiCase(u"_") > 0);
+}
+
+void test::oustring::Compare::compareTo()
+{
+ // test that embedded NUL does not stop the compare
+ // this sort of thing is how we assign shape ids in oox
+ sal_Unicode str1[2] = { '\0', 'x' };
+ sal_Unicode str2[2] = { '\0', 'y' };
+
+ OUString s1(str1, 2);
+ OUString s2(str2, 2);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), s1.compareTo(s1));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), s2.compareTo(s2));
+ CPPUNIT_ASSERT(s1.compareTo(s2) < 0);
+ CPPUNIT_ASSERT(s2.compareTo(s1) > 0);
+ CPPUNIT_ASSERT(s1.compareTo(OUStringConcatenation(s2 + "y")) < 0);
+ CPPUNIT_ASSERT(s2.compareTo(OUStringConcatenation(s1 + "x")) > 0);
+ CPPUNIT_ASSERT(OUString(s1 + "x").compareTo(s2) < 0);
+ CPPUNIT_ASSERT(OUString(s2 + "y").compareTo(s1) > 0);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_oustring_concat.cxx b/sal/qa/rtl/strings/test_oustring_concat.cxx
new file mode 100644
index 000000000..5a11da892
--- /dev/null
+++ b/sal/qa/rtl/strings/test_oustring_concat.cxx
@@ -0,0 +1,213 @@
+/* -*- 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/.
+ */
+
+// activate support for detecting errors instead of getting compile errors
+#define RTL_STRING_UNITTEST_CONCAT
+extern bool rtl_string_unittest_invalid_concat;
+
+#include <sal/types.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <string>
+#include <typeinfo>
+
+using namespace rtl;
+
+namespace CppUnit
+{
+template<> struct assertion_traits<std::type_info>
+{
+ static bool equal(std::type_info const & x, std::type_info const & y) { return x == y; }
+
+ static std::string toString(std::type_info const & x) { return x.name(); }
+};
+} // namespace
+
+namespace test::oustring {
+
+class StringConcat : public CppUnit::TestFixture
+{
+private:
+ void checkConcat();
+ void checkConcatAsciiL();
+ void checkEnsureCapacity();
+ void checkAppend();
+ void checkInvalid();
+
+CPPUNIT_TEST_SUITE(StringConcat);
+CPPUNIT_TEST(checkConcat);
+CPPUNIT_TEST(checkConcatAsciiL);
+CPPUNIT_TEST(checkEnsureCapacity);
+CPPUNIT_TEST(checkAppend);
+CPPUNIT_TEST(checkInvalid);
+CPPUNIT_TEST_SUITE_END();
+};
+
+void test::oustring::StringConcat::checkConcat()
+{
+// All the extra () are to protect commas against being treated as separators of macro arguments.
+ CPPUNIT_ASSERT_EQUAL( OUString(), OUString(OUString() + OUString()));
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobar" ), OUString( OUString( "foo" ) + OUString( "bar" )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, OUString > )), typeid( OUString( "foo" ) + OUString( "bar" )));
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobar" ), OUString( OUString( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, const char[ 4 ] > )), typeid( OUString( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobarbaz" ), OUString( OUString( "foo" ) + "bar" + "baz" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringConcat< OUString, const char[ 4 ] >, const char[ 4 ] > )), typeid( OUString( "foo" ) + "bar" + "baz" ));
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobar" ), OUString( OUStringBuffer( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringBuffer, const char[ 4 ] > )), typeid( OUStringBuffer( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobar" ), OUString( OUStringLiteral( u"foo" ) + "bar" ));
+#if defined __GNUC__ && __GNUC__ <= 11 && !defined __clang__
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringLiteral<4>, const char[ 4 ] > )), typeid( OUStringLiteral<4>( u"foo" ) + "bar" ));
+ // the explicit OUStringLiteral<4> template argument in the unevaluated typeid context
+ // is needed by some GCC versions, see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96878>
+ // "Failed class template argument deduction in unevaluated, parenthesized context"
+#else
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringLiteral<4>, const char[ 4 ] > )), typeid( OUStringLiteral( u"foo" ) + "bar" ));
+#endif
+ const char d1[] = "xyz";
+ CPPUNIT_ASSERT_EQUAL( OUString( "fooxyz" ), OUString( OUString( "foo" ) + d1 ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, const char[ 4 ] > )), typeid( OUString( "foo" ) + d1 ));
+ const sal_Unicode* d2 = u"xyz";
+ CPPUNIT_ASSERT_EQUAL( OUString( "fooxyz" ), OUString( OUString( "foo" ) + d2 ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, const sal_Unicode* > )), typeid( OUString( "foo" ) + d2 ));
+ const sal_Unicode d3[] = u"xyz";
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobar" ), OUString( OUString::Concat( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringConcat< rtl::OUStringConcatMarker, const char[ 4 ] >, const char[ 4 ] > )), typeid( OUString::Concat( "foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OUString( "xyzbar" ), OUString( OUString::Concat( d1 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringConcat< rtl::OUStringConcatMarker, const char[ 4 ] >, const char[ 4 ] > )), typeid( OUString::Concat( d1 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobar" ), OUString( OUString::Concat( u"foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringConcat< rtl::OUStringConcatMarker, const sal_Unicode[ 4 ] >, const char[ 4 ] > )), typeid( OUString::Concat( u"foo" ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OUString( "xyzbar" ), OUString( OUString::Concat( d2 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringConcat< rtl::OUStringConcatMarker, const sal_Unicode* >, const char[ 4 ] > )), typeid( OUString::Concat( d2 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL( OUString( "xyzbar" ), OUString( OUString::Concat( d3 ) + "bar" ));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringConcat< rtl::OUStringConcatMarker, const sal_Unicode[ 4 ] >, const char[ 4 ] > )), typeid( OUString::Concat( d3 ) + "bar" ));
+
+ CPPUNIT_ASSERT_EQUAL( OUString( "num10" ), OUString( OUString( "num" ) + OUString::number( 10 )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, OUStringNumber< int > > )), typeid( OUString( "num" ) + OUString::number( 10 )));
+ CPPUNIT_ASSERT_EQUAL( OUString( "num10" ), OUString( OUString( "num" ) + OUString::number( 10L )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, OUStringNumber< long long > > )), typeid( OUString( "num" ) + OUString::number( 10L )));
+ CPPUNIT_ASSERT_EQUAL( OUString( "num10" ), OUString( OUString( "num" ) + OUString::number( 10ULL )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, OUStringNumber< unsigned long long > > )), typeid( OUString( "num" ) + OUString::number( 10ULL )));
+ CPPUNIT_ASSERT_EQUAL( OUString( "num10.5" ), OUString( OUString( "num" ) + OUString::number( 10.5f )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, OUStringNumber< float > > )), typeid( OUString( "num" ) + OUString::number( 10.5f )));
+ CPPUNIT_ASSERT_EQUAL( OUString( "num10.5" ), OUString( OUString( "num" ) + OUString::number( 10.5 )));
+ CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUString, OUStringNumber< double > > )), typeid( OUString( "num" ) + OUString::number( 10.5 )));
+}
+
+void test::oustring::StringConcat::checkConcatAsciiL()
+{
+ {
+ OUString s("foo");
+ s += "";
+ CPPUNIT_ASSERT_EQUAL(OUString("foo"), s);
+ }
+ {
+ OUString s("foo");
+ s += "bar";
+ CPPUNIT_ASSERT_EQUAL(OUString("foobar"), s);
+ }
+}
+
+void test::oustring::StringConcat::checkEnsureCapacity()
+{
+ rtl_uString* str = nullptr;
+ rtl_uString_newFromLiteral( &str, "test", strlen( "test" ), 0 );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length );
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+
+ rtl_uString* oldStr = str;
+ rtl_uString_ensureCapacity( &str, 4 ); // should be no-op
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length );
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+ CPPUNIT_ASSERT_EQUAL( str, oldStr );
+
+ rtl_uString_acquire( oldStr );
+ CPPUNIT_ASSERT_EQUAL( 2, int( str->refCount ));
+ rtl_uString_ensureCapacity( &str, 4 );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length );
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+ // a copy was forced because of refcount
+ CPPUNIT_ASSERT( oldStr != str );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(0), rtl_ustr_compare( oldStr->buffer, str->buffer ) );
+ CPPUNIT_ASSERT_EQUAL( 1, int( oldStr->refCount ));
+ rtl_uString_release( str );
+ str = oldStr;
+
+ rtl_uString_acquire( oldStr );
+ rtl_uString_ensureCapacity( &str, 1024 );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 4 ), str->length ); // size is still 4
+ CPPUNIT_ASSERT_EQUAL( 1, int( str->refCount ));
+ CPPUNIT_ASSERT( oldStr != str );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(0), rtl_ustr_compare( oldStr->buffer, str->buffer ) );
+ CPPUNIT_ASSERT_EQUAL( 1, int( oldStr->refCount ));
+ // but there should be extra capacity
+ for( int i = 0;
+ i < 20;
+ ++i )
+ str->buffer[ str->length + i ] = '0';
+ str->length += 20;
+ rtl_uString_release( str );
+ rtl_uString_release( oldStr );
+}
+
+void test::oustring::StringConcat::checkAppend()
+{
+ OUString str( "foo" );
+ str += OUStringLiteral( u"bar" ) + "baz";
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobarbaz" ), str );
+ OUStringBuffer buf( "foo" );
+ buf.append( OUStringLiteral( u"bar" ) + "baz" );
+ CPPUNIT_ASSERT_EQUAL( OUString( "foobarbaz" ), buf.makeStringAndClear());
+}
+
+#define INVALID_CONCAT( expression ) \
+ ( \
+ rtl_string_unittest_invalid_concat = false, \
+ ( void ) OUString( expression ), \
+ rtl_string_unittest_invalid_concat )
+
+void test::oustring::StringConcat::checkInvalid()
+{
+ CPPUNIT_ASSERT( !INVALID_CONCAT( OUString() + OUString()));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + OString( "b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + OStringBuffer( "b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + static_cast<const char*>("b") ));
+ char d[] = "b";
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + d ));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + static_cast<char*>(d) ));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + OStringLiteral( "b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + OString::Concat( "b" )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + 1 ));
+ rtl_String* rs = nullptr;
+ rtl_uString* rus = nullptr;
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "b" ) + rs ));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "b" ) + rus ));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString( "a" ) + OString::number( 10 )));
+ CPPUNIT_ASSERT( INVALID_CONCAT( OUString::number( 0 ) + OString::number( 10 )));
+
+#if 0
+ // Should fail to compile, to avoid use of OUStringConcat lvalues that
+ // contain dangling references to temporaries:
+ auto const conc = OUStringLiteral("foo") + "bar";
+ (void) OUString(conc);
+#endif
+}
+
+} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::StringConcat);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_oustring_convert.cxx b/sal/qa/rtl/strings/test_oustring_convert.cxx
new file mode 100644
index 000000000..da930a03f
--- /dev/null
+++ b/sal/qa/rtl/strings/test_oustring_convert.cxx
@@ -0,0 +1,177 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/macros.h>
+
+namespace test::oustring {
+
+class Convert: public CppUnit::TestFixture
+{
+private:
+ void convertToString();
+
+ CPPUNIT_TEST_SUITE(Convert);
+ CPPUNIT_TEST(convertToString);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::Convert);
+
+namespace {
+
+struct TestConvertToString
+{
+ sal_Unicode aSource[100];
+ sal_Int32 nLength;
+ rtl_TextEncoding nEncoding;
+ sal_uInt32 nFlags;
+ char const * pStrict;
+ char const * pRelaxed;
+};
+
+void testConvertToString(TestConvertToString const & rTest)
+{
+ const OUString aSource(rTest.aSource, rTest.nLength);
+ OString aStrict(RTL_CONSTASCII_STRINGPARAM("12345"));
+ bool bSuccess = aSource.convertToString(&aStrict, rTest.nEncoding,
+ rTest.nFlags);
+ OString aRelaxed(OUStringToOString(aSource, rTest.nEncoding,
+ rTest.nFlags));
+
+ OStringBuffer aPrefix;
+ aPrefix.append("{");
+ for (sal_Int32 i = 0; i < rTest.nLength; ++i)
+ {
+ aPrefix.append("U+");
+ aPrefix.append(static_cast< sal_Int32 >(rTest.aSource[i]), 16);
+ if (i + 1 < rTest.nLength)
+ aPrefix.append(",");
+ }
+ aPrefix.append("}, ");
+ aPrefix.append(static_cast< sal_Int32 >(rTest.nEncoding));
+ aPrefix.append(", 0x");
+ aPrefix.append(static_cast< sal_Int32 >(rTest.nFlags), 16);
+ aPrefix.append(" -> ");
+
+ if (bSuccess)
+ {
+ if (rTest.pStrict == nullptr || aStrict != rTest.pStrict)
+ {
+ OStringBuffer aMessage(aPrefix);
+ aMessage.append("strict = \"");
+ aMessage.append(aStrict);
+ aMessage.append("\"");
+ CPPUNIT_ASSERT_MESSAGE(aMessage.getStr(), false);
+ }
+ }
+ else
+ {
+ if (aStrict != "12345")
+ {
+ OStringBuffer aMessage(aPrefix);
+ aMessage.append("modified output");
+ CPPUNIT_ASSERT_MESSAGE(aMessage.getStr(), false);
+ }
+ if (rTest.pStrict != nullptr)
+ {
+ OStringBuffer aMessage(aPrefix);
+ aMessage.append("failed");
+ CPPUNIT_ASSERT_MESSAGE(aMessage.getStr(), false);
+ }
+ }
+ if (aRelaxed != rTest.pRelaxed)
+ {
+ OStringBuffer aMessage(aPrefix);
+ aMessage.append("relaxed = \"");
+ aMessage.append(aRelaxed);
+ aMessage.append("\"");
+ CPPUNIT_ASSERT_MESSAGE(aMessage.getStr(), false);
+ }
+}
+
+}
+
+void test::oustring::Convert::convertToString()
+{
+ TestConvertToString const aTests[]
+ = { { { 0 },
+ 0,
+ RTL_TEXTENCODING_ASCII_US,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR,
+ "",
+ "" },
+ { { 0 },
+ 0,
+ RTL_TEXTENCODING_ASCII_US,
+ OUSTRING_TO_OSTRING_CVTFLAGS,
+ "",
+ "" },
+ { { 0x0041,0x0042,0x0043 },
+ 3,
+ RTL_TEXTENCODING_ASCII_US,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR,
+ "ABC",
+ "ABC" },
+ { { 0x0041,0x0042,0x0043 },
+ 3,
+ RTL_TEXTENCODING_ASCII_US,
+ OUSTRING_TO_OSTRING_CVTFLAGS,
+ "ABC",
+ "ABC" },
+ { { 0xB800 },
+ 1,
+ RTL_TEXTENCODING_ISO_2022_JP,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR,
+ nullptr,
+ "" },
+ { { 0x3001, 0xB800 },
+ 2,
+ RTL_TEXTENCODING_ISO_2022_JP,
+ OUSTRING_TO_OSTRING_CVTFLAGS,
+ "\x1b\x24\x42\x21\x22\x1b\x28\x42\x3f",
+ "\x1b\x24\x42\x21\x22\x1b\x28\x42\x3f" },
+ { { 0x0041,0x0100,0x0042 },
+ 3,
+ RTL_TEXTENCODING_ISO_8859_1,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR,
+ nullptr,
+ "A" },
+ { { 0x0041,0x0100,0x0042 },
+ 3,
+ RTL_TEXTENCODING_ISO_8859_1,
+ OUSTRING_TO_OSTRING_CVTFLAGS,
+ "A?B",
+ "A?B" } };
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aTests); ++i)
+ testConvertToString(aTests[i]);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_oustring_endswith.cxx b/sal/qa/rtl/strings/test_oustring_endswith.cxx
new file mode 100644
index 000000000..bf01577e2
--- /dev/null
+++ b/sal/qa/rtl/strings/test_oustring_endswith.cxx
@@ -0,0 +1,113 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/string.h>
+#include <rtl/string.hxx>
+#include <rtl/textenc.h>
+#include <rtl/ustring.hxx>
+#include <sal/macros.h>
+
+namespace test::oustring {
+
+class EndsWith: public CppUnit::TestFixture
+{
+private:
+ void endsWith();
+
+ CPPUNIT_TEST_SUITE(EndsWith);
+ CPPUNIT_TEST(endsWith);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::EndsWith);
+
+namespace {
+
+void appendString(OStringBuffer & buffer, OString const & string)
+{
+ buffer.append('"');
+ for (int i = 0; i < string.getLength(); ++i) {
+ char c = string[i];
+ if (c < ' ' || c == '"' || c == '\\' || c > '~') {
+ buffer.append('\\');
+ sal_Int32 n = static_cast< sal_Int32 >(
+ static_cast< unsigned char >(c));
+ if (n < 16) {
+ buffer.append('0');
+ }
+ buffer.append(n, 16);
+ } else {
+ buffer.append(c);
+ }
+ }
+ buffer.append('"');
+}
+
+}
+
+void test::oustring::EndsWith::endsWith()
+{
+ struct Data {
+ char const * str1;
+ sal_Int32 str1Len;
+ char const * str2;
+ sal_Int32 str2Len;
+ bool endsWith;
+ };
+ Data const data[] = {
+ { RTL_CONSTASCII_STRINGPARAM(""), RTL_CONSTASCII_STRINGPARAM(""),
+ true },
+ { RTL_CONSTASCII_STRINGPARAM("abc"), RTL_CONSTASCII_STRINGPARAM(""),
+ true },
+ { RTL_CONSTASCII_STRINGPARAM(""), RTL_CONSTASCII_STRINGPARAM("abc"),
+ false },
+ { RTL_CONSTASCII_STRINGPARAM("ABC"), RTL_CONSTASCII_STRINGPARAM("abc"),
+ true },
+ { RTL_CONSTASCII_STRINGPARAM("abcd"), RTL_CONSTASCII_STRINGPARAM("bcd"),
+ true },
+ { RTL_CONSTASCII_STRINGPARAM("bcd"), RTL_CONSTASCII_STRINGPARAM("abcd"),
+ false },
+ { RTL_CONSTASCII_STRINGPARAM("a\0b\0c"),
+ RTL_CONSTASCII_STRINGPARAM("b\0c"), true },
+ { RTL_CONSTASCII_STRINGPARAM("a\0b\0c"),
+ RTL_CONSTASCII_STRINGPARAM("b"), false } };
+ for (size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ OStringBuffer msg;
+ appendString(msg, OString(data[i].str1, data[i].str1Len));
+ msg.append(".endsWithIgnoreAsciiCaseAsciiL(");
+ appendString(msg, OString(data[i].str2, data[i].str2Len));
+ msg.append(") == ");
+ msg.append(data[i].endsWith);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ msg.getStr(),
+ data[i].endsWith,
+ OUString(
+ data[i].str1, data[i].str1Len,
+ RTL_TEXTENCODING_ASCII_US).endsWithIgnoreAsciiCaseAsciiL(
+ data[i].str2, data[i].str2Len));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_oustring_startswith.cxx b/sal/qa/rtl/strings/test_oustring_startswith.cxx
new file mode 100644
index 000000000..a74671e6e
--- /dev/null
+++ b/sal/qa/rtl/strings/test_oustring_startswith.cxx
@@ -0,0 +1,38 @@
+/* -*- 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/.
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/ustring.hxx>
+
+namespace test::oustring {
+
+class StartsWith: public CppUnit::TestFixture
+{
+private:
+ void startsWith();
+
+ CPPUNIT_TEST_SUITE(StartsWith);
+ CPPUNIT_TEST(startsWith);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::StartsWith);
+
+void test::oustring::StartsWith::startsWith()
+{
+ CPPUNIT_ASSERT( OUString( "foobar" ).startsWith( "foo" ));
+ CPPUNIT_ASSERT( !OUString( "foo" ).startsWith( "foobar" ));
+ CPPUNIT_ASSERT( !OUString( "foobar" ).startsWith( "oo" ));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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 000000000..0caa3fc03
--- /dev/null
+++ b/sal/qa/rtl/strings/test_oustring_stringliterals.cxx
@@ -0,0 +1,432 @@
+/* -*- 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/.
+ */
+
+// activate the extra needed ctor
+#define RTL_STRING_UNITTEST
+
+#include <sal/config.h>
+
+#include <string>
+#include <string_view>
+#include <utility>
+
+#include <o3tl/cppunittraitshelper.hxx>
+#include <sal/types.h>
+#include <config_global.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/string.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+
+extern bool rtl_string_unittest_const_literal;
+bool rtl_string_unittest_invalid_conversion;
+
+namespace test::oustring {
+
+class StringLiterals: public CppUnit::TestFixture
+{
+private:
+ void checkCtors();
+ void checkConstexprCtor();
+ void checkUsage();
+ void checkBuffer();
+ void checkOUStringLiteral();
+ void checkOUStringChar();
+ void checkUtf16();
+ void checkEmbeddedNul();
+
+ void testcall( const char str[] );
+
+ // Check that OUStringLiteral ctor is actually constexpr:
+ static constexpr rtlunittest::OUStringLiteral dummy{u"dummy"};
+
+CPPUNIT_TEST_SUITE(StringLiterals);
+CPPUNIT_TEST(checkCtors);
+CPPUNIT_TEST(checkConstexprCtor);
+CPPUNIT_TEST(checkUsage);
+CPPUNIT_TEST(checkBuffer);
+CPPUNIT_TEST(checkOUStringLiteral);
+CPPUNIT_TEST(checkOUStringChar);
+CPPUNIT_TEST(checkUtf16);
+CPPUNIT_TEST(checkEmbeddedNul);
+CPPUNIT_TEST_SUITE_END();
+};
+
+// reset the flag, evaluate the expression and return
+// whether the string literal ctor was used (i.e. whether the conversion was valid)
+template<typename T> static bool VALID_CONVERSION( T && expression )
+{
+ rtl_string_unittest_invalid_conversion = false;
+ // OK to std::forward expression twice; what is relevant in both ctor calls
+ // is not the content of the passed argument (which is ignored anyway by the
+ // special RTL_STRING_UNITTEST ctors) but only its type:
+ ( void ) rtl::OUString( std::forward<T>(expression) );
+ ( void ) rtl::OUStringBuffer( std::forward<T>(expression) );
+ return !rtl_string_unittest_invalid_conversion;
+}
+template<typename T> static bool VALID_CONVERSION_CALL( T f )
+{
+ rtl_string_unittest_invalid_conversion = false;
+ ( void ) rtl::OUString( f() );
+ ( void ) rtl::OUStringBuffer( f() );
+ return !rtl_string_unittest_invalid_conversion;
+}
+
+void test::oustring::StringLiterals::checkCtors()
+{
+ CPPUNIT_ASSERT( VALID_CONVERSION( "test" ));
+ const char good1[] = "test";
+ CPPUNIT_ASSERT( VALID_CONVERSION( good1 ));
+
+ CPPUNIT_ASSERT( !VALID_CONVERSION( static_cast<const char*>("test") ));
+ const char* bad1 = good1;
+ CPPUNIT_ASSERT( !VALID_CONVERSION( bad1 ));
+ char bad2[] = "test";
+ CPPUNIT_ASSERT( !VALID_CONVERSION( bad2 ));
+ char* bad3 = bad2;
+ CPPUNIT_ASSERT( !VALID_CONVERSION( bad3 ));
+ const char* bad4[] = { "test1" };
+ 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 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.
+ CPPUNIT_ASSERT_EQUAL( rtl::OUString( "" ), rtl::OUString( "" ));
+ CPPUNIT_ASSERT_EQUAL( rtl::OUString( "ab" ), rtl::OUString( "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( "\0" ));
+ CPPUNIT_ASSERT_EQUAL( rtl::OUString( "a\0b" ), rtl::OUString( "a\0b" ));
+#endif
+}
+
+void test::oustring::StringLiterals::testcall( const char str[] )
+{
+ CPPUNIT_ASSERT(
+ !VALID_CONVERSION_CALL([&str]() { return rtl::OUString(str); }));
+}
+
+void test::oustring::StringLiterals::checkConstexprCtor()
+{
+#if __cplusplus >= 202002L
+ static constinit
+#endif
+ rtl::OUString s(dummy);
+ CPPUNIT_ASSERT_EQUAL(oslInterlockedCount(0x40000000), s.pData->refCount);
+ // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), s.getLength());
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("dummy"), s);
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<void const *>(dummy.getStr()), static_cast<void const *>(s.getStr()));
+}
+
+void test::oustring::StringLiterals::checkUsage()
+{
+// simply check that all string literal based calls work as expected
+// also check that they really use string literal overload and do not convert to OUString
+ rtl::OUString foo( "foo" );
+ rtl::OUString FoO( "FoO" );
+ rtl::OUString foobarfoo( "foobarfoo" );
+ rtl::OUString foobar( "foobar" );
+ rtl::OUString FooBaRfoo( "FooBaRfoo" );
+ rtl::OUString FooBaR( "FooBaR" );
+ rtl::OUString bar( "bar" );
+ rtl::OUString test( "test" );
+
+ rtl_string_unittest_const_literal = false; // start checking for OUString conversions
+ CPPUNIT_ASSERT_EQUAL( foo, rtl::OUString() = "foo" );
+ CPPUNIT_ASSERT( FoO.equalsIgnoreAsciiCase( "fOo" ));
+ CPPUNIT_ASSERT( foobarfoo.match( "bar", 3 ));
+ CPPUNIT_ASSERT( foobar.match( "foo" ));
+ CPPUNIT_ASSERT( FooBaRfoo.matchIgnoreAsciiCase( "bAr", 3 ));
+ CPPUNIT_ASSERT( FooBaR.matchIgnoreAsciiCase( "fOo" ));
+ CPPUNIT_ASSERT( foobar.startsWith( "foo" ));
+ CPPUNIT_ASSERT( FooBaR.startsWithIgnoreAsciiCase( "foo" ));
+ CPPUNIT_ASSERT( foobar.endsWith( "bar" ));
+ CPPUNIT_ASSERT( FooBaR.endsWithIgnoreAsciiCase( "bar" ));
+ CPPUNIT_ASSERT( bool(foo == "foo") );
+ CPPUNIT_ASSERT( bool("foo" == foo) );
+ CPPUNIT_ASSERT( foo != "bar" );
+ CPPUNIT_ASSERT( "foo" != bar );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.indexOf( "foo", 1 ) );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(6), foobarfoo.lastIndexOf( "foo" ) );
+ CPPUNIT_ASSERT( bool(foobarfoo.replaceFirst( "foo", test ) == "testbarfoo") );
+ CPPUNIT_ASSERT( bool(foobarfoo.replaceFirst( "foo", "test" ) == "testbarfoo") );
+ CPPUNIT_ASSERT( bool(foobarfoo.replaceAll( "foo", test ) == "testbartest") );
+ CPPUNIT_ASSERT( bool(foobarfoo.replaceAll( "foo", "test" ) == "testbartest") );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(0), foo.reverseCompareTo( "foo" ) );
+ // if this is not true, some of the calls above converted to OUString
+ CPPUNIT_ASSERT( !rtl_string_unittest_const_literal );
+}
+
+void test::oustring::StringLiterals::checkBuffer()
+{
+ rtl::OUStringBuffer buf;
+ buf.append( "foo" );
+ CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foo" ), buf.toString());
+ buf.append( "bar" );
+ CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foobar" ), buf.toString());
+ buf.insert( 3, "baz" );
+ CPPUNIT_ASSERT_EQUAL( rtl::OUString( "foobazbar" ), buf.toString());
+ char d[] = "d";
+ CPPUNIT_ASSERT( !VALID_CONVERSION( buf.append( rtl::OUString( d ))));
+ CPPUNIT_ASSERT( !VALID_CONVERSION( buf.append( rtl::OUStringBuffer( d ))));
+}
+
+namespace {
+
+rtl::OUString conditional(bool flag) {
+ return rtl::OUString::Concat(flag ? std::u16string_view(u"a") : std::u16string_view(u"bb"))
+ + "c";
+}
+
+}
+
+void test::oustring::StringLiterals::checkOUStringLiteral()
+{
+ CPPUNIT_ASSERT(bool(conditional(true) == "ac"));
+ CPPUNIT_ASSERT(bool(conditional(false) == "bbc"));
+
+ static constexpr rtlunittest::OUStringLiteral s1lit(u"abc");
+ rtl::OUString s1(s1lit);
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abc"), s1);
+ static constexpr rtlunittest::OUStringLiteral de(u"de");
+ s1 = de;
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("de"), s1);
+ s1 += rtlunittest::OUStringLiteral(u"fde");
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("defde"), s1);
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(0),
+ s1.reverseCompareTo(rtlunittest::OUStringLiteral(u"defde")));
+ CPPUNIT_ASSERT(
+ s1.equalsIgnoreAsciiCase(rtlunittest::OUStringLiteral(u"DEFDE")));
+ CPPUNIT_ASSERT(s1.match(rtlunittest::OUStringLiteral(u"fde"), 2));
+ CPPUNIT_ASSERT(
+ s1.matchIgnoreAsciiCase(rtlunittest::OUStringLiteral(u"FDE"), 2));
+ rtl::OUString s2;
+ CPPUNIT_ASSERT(s1.startsWith(rtlunittest::OUStringLiteral(u"de"), &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("fde"), s2);
+ CPPUNIT_ASSERT(
+ s1.startsWithIgnoreAsciiCase(
+ rtlunittest::OUStringLiteral(u"DEFD"), &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("e"), s2);
+ CPPUNIT_ASSERT(s1.endsWith(rtlunittest::OUStringLiteral(u"de"), &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("def"), s2);
+ CPPUNIT_ASSERT(
+ s1.endsWithIgnoreAsciiCase(rtlunittest::OUStringLiteral(u"EFDE"), &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("d"), s2);
+ static constexpr rtlunittest::OUStringLiteral defde(u"defde");
+ CPPUNIT_ASSERT(bool(s1 == defde));
+ CPPUNIT_ASSERT(bool(defde == s1));
+ static constexpr rtlunittest::OUStringLiteral abc(u"abc");
+ CPPUNIT_ASSERT(s1 != abc);
+ CPPUNIT_ASSERT(abc != s1);
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(3), s1.indexOf(rtlunittest::OUStringLiteral(u"de"), 1));
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(3), s1.lastIndexOf(rtlunittest::OUStringLiteral(u"de")));
+ sal_Int32 i = 0;
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfde"),
+ s1.replaceFirst(
+ rtlunittest::OUStringLiteral(u"de"), rtl::OUString("abc"), &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfde"),
+ s1.replaceFirst(
+ rtl::OUString("de"), rtlunittest::OUStringLiteral(u"abc"), &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfde"),
+ s1.replaceFirst(
+ rtlunittest::OUStringLiteral(u"de"),
+ rtlunittest::OUStringLiteral(u"abc"), &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfde"),
+ s1.replaceFirst(rtlunittest::OUStringLiteral(u"de"), "abc", &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfde"),
+ s1.replaceFirst("de", rtlunittest::OUStringLiteral(u"abc"), &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfabc"),
+ s1.replaceAll(
+ rtlunittest::OUStringLiteral(u"de"), rtl::OUString("abc")));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfabc"),
+ s1.replaceAll(
+ rtl::OUString("de"), rtlunittest::OUStringLiteral(u"abc")));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfabc"),
+ s1.replaceAll(
+ rtlunittest::OUStringLiteral(u"de"),
+ rtlunittest::OUStringLiteral(u"abc")));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfabc"),
+ s1.replaceAll(rtlunittest::OUStringLiteral(u"de"), "abc"));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcfabc"),
+ s1.replaceAll("de", rtlunittest::OUStringLiteral(u"abc")));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcdef"),
+ rtl::OUString(
+ rtl::OUString("abc") + rtlunittest::OUStringLiteral(u"def")));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcdef"),
+ rtl::OUString(
+ rtlunittest::OUStringLiteral(u"abc") + rtl::OUString("def")));
+ rtl::OUStringBuffer b(rtlunittest::OUStringLiteral(u"abc"));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abc"), b.toString());
+ b.append(rtlunittest::OUStringLiteral(u"def"));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abcdef"), b.toString());
+ b.insert(2, rtlunittest::OUStringLiteral(u"gabab"));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abgababcdef"), b.toString());
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(3), b.indexOf(rtlunittest::OUStringLiteral(u"ab"), 1));
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(5), b.lastIndexOf(rtlunittest::OUStringLiteral(u"ab")));
+}
+
+void test::oustring::StringLiterals::checkOUStringChar()
+{
+ auto l1 = rtlunittest::OUStringChar('A');
+ CPPUNIT_ASSERT_EQUAL(u'A', l1.c);
+
+ char const c2 = 'A';
+ auto l2 = rtlunittest::OUStringChar(c2);
+ CPPUNIT_ASSERT_EQUAL(u'A', l2.c);
+
+ char c3 = 'A'; auto l3 = rtlunittest::OUStringChar(c3);
+ CPPUNIT_ASSERT_EQUAL(u'A', l3.c);
+
+ auto l4 = rtlunittest::OUStringChar(u'A');
+ CPPUNIT_ASSERT_EQUAL(u'A', l4.c);
+
+ sal_Unicode const c5 = 0x100;
+ auto l5 = rtlunittest::OUStringChar(c5);
+ CPPUNIT_ASSERT_EQUAL(c5, l5.c);
+
+ rtl::OUString s1{rtlunittest::OUStringChar('A')};
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), s1.getLength());
+ CPPUNIT_ASSERT_EQUAL(u'A', s1[0]);
+
+ CPPUNIT_ASSERT_EQUAL(
+ true, rtl::OUString("A") == rtlunittest::OUStringChar('A'));
+ CPPUNIT_ASSERT_EQUAL(
+ false, rtl::OUString("AB") == rtlunittest::OUStringChar('A'));
+ CPPUNIT_ASSERT_EQUAL(
+ false, rtl::OUString("A") != rtlunittest::OUStringChar('A'));
+ CPPUNIT_ASSERT_EQUAL(
+ true, rtl::OUString("AB") != rtlunittest::OUStringChar('A'));
+
+ rtl::OUString s2("A" + rtlunittest::OUStringChar('b'));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), s2.getLength());
+ CPPUNIT_ASSERT_EQUAL(u'A', s2[0]);
+ CPPUNIT_ASSERT_EQUAL(u'b', s2[1]);
+}
+
+void test::oustring::StringLiterals::checkUtf16() {
+ rtl::OUString s1(u"abc");
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abc"), s1);
+ s1 = u"de";
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("de"), s1);
+ s1 += u"fde";
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("defde"), s1);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), s1.reverseCompareTo(u"defde"));
+ CPPUNIT_ASSERT(s1.equalsIgnoreAsciiCase(u"DEFDE"));
+ CPPUNIT_ASSERT(s1.match(u"fde", 2));
+ CPPUNIT_ASSERT(s1.matchIgnoreAsciiCase(u"FDE", 2));
+ rtl::OUString s2;
+ CPPUNIT_ASSERT(s1.startsWith(u"de", &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString(u"fde"), s2);
+ CPPUNIT_ASSERT(s1.startsWithIgnoreAsciiCase(u"DEFD", &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString(u"e"), s2);
+ CPPUNIT_ASSERT(s1.endsWith(u"de", &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString(u"def"), s2);
+ CPPUNIT_ASSERT(s1.endsWithIgnoreAsciiCase(u"EFDE", &s2));
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString(u"d"), s2);
+ CPPUNIT_ASSERT(bool(s1 == u"defde"));
+ CPPUNIT_ASSERT(bool(u"defde" == s1));
+ CPPUNIT_ASSERT(s1 != u"abc");
+ CPPUNIT_ASSERT(u"abc" != s1);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), s1.indexOf(u"de", 1));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), s1.lastIndexOf(u"de"));
+ sal_Int32 i = 0;
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfde"),
+ s1.replaceFirst(u"de", rtl::OUString("abc"), &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfde"),
+ s1.replaceFirst(rtl::OUString("de"), u"abc", &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfde"), s1.replaceFirst(u"de", u"abc", &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfde"), s1.replaceFirst(u"de", "abc", &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfde"), s1.replaceFirst("de", u"abc", &i));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfabc"), s1.replaceAll(u"de", rtl::OUString("abc")));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfabc"), s1.replaceAll(rtl::OUString("de"), u"abc"));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfabc"), s1.replaceAll(u"de", u"abc"));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfabc"), s1.replaceAll(u"de", "abc"));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString(u"abcfabc"), s1.replaceAll("de", u"abc"));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcdef"), rtl::OUString(rtl::OUString("abc") + u"def"));
+ CPPUNIT_ASSERT_EQUAL(
+ rtl::OUString("abcdef"), rtl::OUString(u"abc" + rtl::OUString("def")));
+ rtl::OUStringBuffer b(u"abc");
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abc"), b.toString());
+ b.append(u"def");
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abcdef"), b.toString());
+ b.insert(2, u"gabab");
+ CPPUNIT_ASSERT_EQUAL(rtl::OUString("abgababcdef"), b.toString());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), b.indexOf(u"ab", 1));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), b.lastIndexOf(u"ab"));
+}
+
+void test::oustring::StringLiterals::checkEmbeddedNul() {
+ using namespace std::literals;
+ rtl::OUString const s("foobar");
+ constexpr char16_t const a[] = u"foo\0hidden";
+ char16_t const * const p = a;
+ CPPUNIT_ASSERT(s.startsWith(a));
+ CPPUNIT_ASSERT(s.startsWith(p));
+ CPPUNIT_ASSERT(s.startsWith(u"foo\0hidden"));
+ CPPUNIT_ASSERT(!s.startsWith(u"foo\0hidden"s));
+ CPPUNIT_ASSERT(!s.startsWith(u"foo\0hidden"sv));
+/*TODO:*/
+ CPPUNIT_ASSERT(!s.startsWith(rtlunittest::OUStringLiteral(a)));
+ CPPUNIT_ASSERT(!s.startsWith(rtlunittest::OUStringLiteral(u"foo\0hidden")));
+/*TODO*/
+}
+
+} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::oustring::StringLiterals);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_strings_defaultstringview.cxx b/sal/qa/rtl/strings/test_strings_defaultstringview.cxx
new file mode 100644
index 000000000..591688b31
--- /dev/null
+++ b/sal/qa/rtl/strings/test_strings_defaultstringview.cxx
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <rtl/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+
+namespace
+{
+class Test : public CppUnit::TestFixture
+{
+ void string() { CPPUNIT_ASSERT_EQUAL(OString(), OString(std::string_view())); }
+
+ void stringbuffer()
+ {
+ // No functions related to OStringBuffer that take a std::string_view or std::u16string_view
+ // argument.
+ }
+
+ void ustring()
+ {
+ CPPUNIT_ASSERT_EQUAL(OUString(), OUString(std::u16string_view()));
+ OUString s1("foo");
+ s1 = std::u16string_view();
+ CPPUNIT_ASSERT_EQUAL(OUString(), s1);
+ OUString s2("foo");
+ s2 += std::u16string_view();
+ CPPUNIT_ASSERT_EQUAL(OUString("foo"), s2);
+ CPPUNIT_ASSERT_GREATER(sal_Int32(0),
+ OUString("foo").reverseCompareTo(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(false, OUString("foo").equalsIgnoreAsciiCase(std::u16string_view()));
+ CPPUNIT_ASSERT_GREATER(sal_Int32(0),
+ OUString("foo").compareToIgnoreAsciiCase(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(true, OUString("foo").match(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(true, OUString("foo").matchIgnoreAsciiCase(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(true, OUString("foo").startsWith(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(true,
+ OUString("foo").startsWithIgnoreAsciiCase(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(true, OUString("foo").endsWith(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(true, OUString("foo").endsWithIgnoreAsciiCase(std::u16string_view()));
+ OUString const foo("foo"); // avoid loplugin:stringconstant, loplugin:stringview
+ CPPUNIT_ASSERT_EQUAL(false, foo == std::u16string_view());
+ CPPUNIT_ASSERT_EQUAL(true, foo != std::u16string_view());
+ CPPUNIT_ASSERT_EQUAL(false, foo < std::u16string_view());
+ CPPUNIT_ASSERT_EQUAL(false, foo <= std::u16string_view());
+ CPPUNIT_ASSERT_EQUAL(true, foo > std::u16string_view());
+ CPPUNIT_ASSERT_EQUAL(true, foo >= std::u16string_view());
+ CPPUNIT_ASSERT_EQUAL(false, std::u16string_view() == foo);
+ CPPUNIT_ASSERT_EQUAL(true, std::u16string_view() != foo);
+ CPPUNIT_ASSERT_EQUAL(true, std::u16string_view() < foo);
+ CPPUNIT_ASSERT_EQUAL(true, std::u16string_view() <= foo);
+ CPPUNIT_ASSERT_EQUAL(false, std::u16string_view() > foo);
+ CPPUNIT_ASSERT_EQUAL(false, std::u16string_view() >= foo);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString("foo").indexOf(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString("foo").lastIndexOf(std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), OUString("foo").lastIndexOf(std::u16string_view(), 3));
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst(std::u16string_view(), std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("barfoo"),
+ OUString("foobarfoo").replaceFirst(std::u16string_view(u"foo"), std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst(std::u16string_view(), std::u16string_view(u"baz")));
+ CPPUNIT_ASSERT_EQUAL(OUString("barfoo"),
+ OUString("foobarfoo").replaceFirst("foo", std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst(std::u16string_view(), "baz"));
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceAll(std::u16string_view(), std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("bar"),
+ OUString("foobarfoo").replaceAll(std::u16string_view(u"foo"), std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceAll(std::u16string_view(), std::u16string_view(u"baz")));
+ CPPUNIT_ASSERT_EQUAL(OUString("bar"),
+ OUString("foobarfoo").replaceAll("foo", std::u16string_view()));
+ CPPUNIT_ASSERT_EQUAL(OUString("foobarfoo"),
+ OUString("foobarfoo").replaceAll(std::u16string_view(), "baz"));
+ CPPUNIT_ASSERT_EQUAL(OUString(), OUString::createFromAscii(std::string_view()));
+ }
+
+ void ustringbuffer()
+ {
+ OUStringBuffer b("foo");
+ b.append(std::u16string_view());
+ CPPUNIT_ASSERT_EQUAL(OUString("foo"), b.toString());
+ }
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(string);
+ CPPUNIT_TEST(stringbuffer);
+ CPPUNIT_TEST(ustring);
+ CPPUNIT_TEST(ustringbuffer);
+ CPPUNIT_TEST_SUITE_END();
+};
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sal/qa/rtl/strings/test_strings_replace.cxx b/sal/qa/rtl/strings/test_strings_replace.cxx
new file mode 100644
index 000000000..3be6e176a
--- /dev/null
+++ b/sal/qa/rtl/strings/test_strings_replace.cxx
@@ -0,0 +1,339 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <sal/types.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/string.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+
+namespace {
+
+OUString s_empty;
+OUString s_bar("bar");
+OUString s_bars("bars");
+OUString s_foo("foo");
+OUString s_other("other");
+OUString s_xa("xa");
+OUString s_xx("xx");
+
+class Test: public CppUnit::TestFixture {
+private:
+ void stringReplaceFirst();
+
+ void stringReplaceAll();
+
+ void ustringReplaceFirst();
+
+ void ustringReplaceFirstAsciiL();
+
+ void ustringReplaceFirstToAsciiL();
+
+ void ustringReplaceFirstAsciiLAsciiL();
+
+ void ustringReplaceAll();
+
+ void ustringReplaceAllAsciiL();
+
+ void ustringReplaceAllToAsciiL();
+
+ void ustringReplaceAllAsciiLAsciiL();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(stringReplaceFirst);
+ CPPUNIT_TEST(stringReplaceAll);
+ CPPUNIT_TEST(ustringReplaceFirst);
+ CPPUNIT_TEST(ustringReplaceFirstAsciiL);
+ CPPUNIT_TEST(ustringReplaceFirstToAsciiL);
+ CPPUNIT_TEST(ustringReplaceFirstAsciiLAsciiL);
+ CPPUNIT_TEST(ustringReplaceAll);
+ CPPUNIT_TEST(ustringReplaceAllAsciiL);
+ CPPUNIT_TEST(ustringReplaceAllToAsciiL);
+ CPPUNIT_TEST(ustringReplaceAllAsciiLAsciiL);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::stringReplaceFirst() {
+ CPPUNIT_ASSERT_EQUAL(
+ OString("otherbarfoo"),
+ OString("foobarfoo").replaceFirst("foo", "other"));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OString("foobarfoo"),
+ OString("foobarfoo").replaceFirst("bars", "other"));
+
+ {
+ sal_Int32 n = 0;
+ CPPUNIT_ASSERT_EQUAL(
+ OString("otherbarfoo"),
+ OString("foobarfoo").replaceFirst("foo", "other", &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), n);
+ }
+
+ {
+ sal_Int32 n = 1;
+ CPPUNIT_ASSERT_EQUAL(
+ OString("foobarother"),
+ OString("foobarfoo").replaceFirst("foo", "other", &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), n);
+ }
+
+ {
+ sal_Int32 n = 4;
+ CPPUNIT_ASSERT_EQUAL(
+ OString("foobarfoo"),
+ OString("foobarfoo").replaceFirst("bar", "other", &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), n);
+ }
+}
+
+void Test::stringReplaceAll() {
+ CPPUNIT_ASSERT_EQUAL(
+ OString("otherbarother"),
+ OString("foobarfoo").replaceAll("foo", "other"));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OString("foobarfoo"),
+ OString("foobarfoo").replaceAll("bars", "other"));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OString("xxa"), OString("xaa").replaceAll("xa", "xx"));
+}
+
+void Test::ustringReplaceFirst() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ OUString("foobarfoo").replaceFirst(s_foo, s_other));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst(s_bars, s_other));
+
+ {
+ sal_Int32 n = 0;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ OUString("foobarfoo").replaceFirst(s_foo, s_other, &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), n);
+ }
+
+ {
+ sal_Int32 n = 1;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarother"),
+ OUString("foobarfoo").replaceFirst(s_foo, s_other, &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), n);
+ }
+
+ {
+ sal_Int32 n = 4;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst(s_bar, s_other, &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), n);
+ }
+}
+
+void Test::ustringReplaceFirstAsciiL() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ OUString("foobarfoo").replaceFirst("foo", s_other));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst("bars", s_other));
+
+ {
+ sal_Int32 n = 0;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ OUString("foobarfoo").replaceFirst("foo", s_other, &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), n);
+ }
+
+ {
+ sal_Int32 n = 1;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarother"),
+ OUString("foobarfoo").replaceFirst("foo", s_other, &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), n);
+ }
+
+ {
+ sal_Int32 n = 4;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst("bar", s_other, &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), n);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(), OUString("xa").replaceFirst("xa", s_empty));
+}
+
+void Test::ustringReplaceFirstToAsciiL() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ OUString("foobarfoo").replaceFirst(s_foo, "other"));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst(s_bars, "other"));
+
+ {
+ sal_Int32 n = 0;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ OUString("foobarfoo").replaceFirst(s_foo, "other", &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), n);
+ }
+
+ {
+ sal_Int32 n = 1;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarother"),
+ OUString("foobarfoo").replaceFirst(s_foo, "other", &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), n);
+ }
+
+ {
+ sal_Int32 n = 4;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceFirst(s_bar, "other", &n));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), n);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(), OUString("xa").replaceFirst(s_xa, ""));
+}
+
+void Test::ustringReplaceFirstAsciiLAsciiL() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ (OUString("foobarfoo").
+ replaceFirst("foo", "other")));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ (OUString("foobarfoo").
+ replaceFirst("bars", "other")));
+
+ {
+ sal_Int32 n = 0;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarfoo"),
+ (OUString("foobarfoo").
+ replaceFirst("foo", "other", &n)));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), n);
+ }
+
+ {
+ sal_Int32 n = 1;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarother"),
+ (OUString("foobarfoo").
+ replaceFirst("foo", "other", &n)));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), n);
+ }
+
+ {
+ sal_Int32 n = 4;
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ (OUString("foobarfoo").
+ replaceFirst("bar", "other", &n)));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), n);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(), OUString("xa").replaceFirst("xa", ""));
+}
+
+void Test::ustringReplaceAll() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarother"),
+ OUString("foobarfoo").replaceAll(s_foo, s_other));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceAll(s_bars, s_other));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("xxa"),
+ OUString("xaa").replaceAll(s_xa, s_xx));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarbaz"), OUString("foobarfoo").replaceAll(u"foo", u"baz", 1));
+}
+
+void Test::ustringReplaceAllAsciiL() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarother"),
+ OUString("foobarfoo").replaceAll("foo", s_other));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceAll("bars", s_other));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("xxa"),
+ OUString("xaa").replaceAll("xa", s_xx));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(), OUString("xa").replaceAll("xa", s_empty));
+}
+
+void Test::ustringReplaceAllToAsciiL() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarother"),
+ OUString("foobarfoo").replaceAll(s_foo, "other"));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ OUString("foobarfoo").replaceAll(s_bars, "other"));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("xxa"),
+ OUString("xaa").replaceAll(s_xa, "xx"));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(), OUString("xa").replaceAll(s_xa, ""));
+}
+
+void Test::ustringReplaceAllAsciiLAsciiL() {
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("otherbarother"),
+ (OUString("foobarfoo").
+ replaceAll("foo", "other")));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("foobarfoo"),
+ (OUString("foobarfoo").
+ replaceAll("bars", "other")));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("xxa"),
+ (OUString("xaa").
+ replaceAll("xa", "xx")));
+
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(), OUString("xa").replaceAll("xa", ""));
+}
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_strings_toint.cxx b/sal/qa/rtl/strings/test_strings_toint.cxx
new file mode 100644
index 000000000..d81525b94
--- /dev/null
+++ b/sal/qa/rtl/strings/test_strings_toint.cxx
@@ -0,0 +1,72 @@
+/* -*- 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/.
+ */
+
+#include <sal/config.h>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace {
+
+template< typename T > class Test: public CppUnit::TestFixture {
+private:
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testToInt32Overflow);
+ CPPUNIT_TEST(testToUInt32Overflow);
+ CPPUNIT_TEST(testToInt64Overflow);
+ CPPUNIT_TEST(testToUInt64Overflow);
+ CPPUNIT_TEST_SUITE_END();
+
+ void testToInt32Overflow() {
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), T("-2147483649").toInt32());
+ CPPUNIT_ASSERT_EQUAL(SAL_MIN_INT32, T("-2147483648").toInt32());
+ CPPUNIT_ASSERT_EQUAL(SAL_MIN_INT32 + 1, T("-2147483647").toInt32());
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32 - 1, T("2147483646").toInt32());
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32, T("2147483647").toInt32());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), T("2147483648").toInt32());
+ }
+
+ void testToUInt32Overflow() {
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_UINT32 - 1, T("4294967294").toUInt32());
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_UINT32, T("4294967295").toUInt32());
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), T("4294967296").toUInt32());
+ }
+
+ void testToInt64Overflow() {
+ CPPUNIT_ASSERT_EQUAL(sal_Int64(0), T("-9223372036854775809").toInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MIN_INT64, T("-9223372036854775808").toInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MIN_INT64 + 1, T("-9223372036854775807").toInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MAX_INT64 - 1, T("9223372036854775806").toInt64());
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT64, T("9223372036854775807").toInt64());
+ CPPUNIT_ASSERT_EQUAL(sal_Int64(0), T("9223372036854775808").toInt64());
+ }
+
+ void testToUInt64Overflow() {
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MAX_UINT64 - 1, T("18446744073709551614").toUInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MAX_UINT64, T("18446744073709551615").toUInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ sal_uInt64(0), T("18446744073709551616").toUInt64());
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test< OString >);
+CPPUNIT_TEST_SUITE_REGISTRATION(Test< OUString >);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/strings/test_strings_valuex.cxx b/sal/qa/rtl/strings/test_strings_valuex.cxx
new file mode 100644
index 000000000..6c9c83644
--- /dev/null
+++ b/sal/qa/rtl/strings/test_strings_valuex.cxx
@@ -0,0 +1,115 @@
+/* -*- 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/.
+ */
+
+#include <sal/types.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <rtl/ustring.hxx>
+#include <iostream>
+
+namespace test::strings {
+
+class valueX : public CppUnit::TestFixture {
+public:
+ void testOBoolean();
+ void testOUBoolean();
+ void testOUInt();
+ void testOInt();
+ void testOUFloat();
+ void testOFloat();
+
+ CPPUNIT_TEST_SUITE(valueX);
+ CPPUNIT_TEST(testOBoolean);
+ CPPUNIT_TEST(testOUBoolean);
+ CPPUNIT_TEST(testOUInt);
+ CPPUNIT_TEST(testOInt);
+ CPPUNIT_TEST(testOUFloat);
+ CPPUNIT_TEST(testOFloat);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test::strings::valueX);
+
+namespace {
+
+template< typename T >
+void testBoolean() {
+ CPPUNIT_ASSERT_EQUAL( T( "false" ), T::boolean( false ) );
+ CPPUNIT_ASSERT_EQUAL( T( "true" ), T::boolean( true ) );
+}
+
+}
+
+void test::strings::valueX::testOBoolean() {
+ testBoolean<OString>();
+}
+
+void test::strings::valueX::testOUBoolean() {
+ testBoolean<OUString>();
+}
+
+template< typename T >
+static void testInt() {
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( 30039062 )));
+
+ // test the overloading resolution
+
+ CPPUNIT_ASSERT_EQUAL( T( "30" ), T( T::number( static_cast< signed char >( 30 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30" ), T( T::number( static_cast< unsigned char >( 30 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039" ), T( T::number( static_cast< short >( 30039 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039" ), T( T::number( static_cast< unsigned short >( 30039 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< int >( 30039062 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< unsigned int >( 30039062 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< long >( 30039062 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< unsigned long >( 30039062 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< long long >( 30039062 ))));
+ // The highest bit set in unsigned long long may not actually work.
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< unsigned long long >( 30039062 ))));
+
+ CPPUNIT_ASSERT_EQUAL( T( "30" ), T( T::number( static_cast< sal_Int8 >( 30 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30" ), T( T::number( static_cast< sal_uInt8 >( 30 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039" ), T( T::number( static_cast< sal_Int16 >( 30039 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039" ), T( T::number( static_cast< sal_uInt16 >( 30039 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< sal_Int32 >( 30039062 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< sal_uInt32 >( 30039062 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< sal_Int64 >( 30039062 ))));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062" ), T( T::number( static_cast< sal_uInt64 >( 30039062 ))));
+
+ // The implementation internally uses sal_Int64 etc. types, so check ranges.
+ assert( sizeof( int ) <= sizeof( sal_Int32 ));
+ assert( sizeof( long ) <= sizeof( sal_Int64 ));
+ assert( sizeof( long long ) <= sizeof( sal_Int64 ));
+ assert( sizeof( unsigned int ) < sizeof( sal_Int64 ));
+}
+
+void test::strings::valueX::testOUInt() {
+ testInt<OUString>();
+}
+
+void test::strings::valueX::testOInt() {
+ testInt<OString>();
+}
+
+template< typename T >
+static void testFloat() {
+ CPPUNIT_ASSERT_EQUAL( T( "39062.2" ), T( T::number( 39062.2f )));
+ CPPUNIT_ASSERT_EQUAL( T( "30039062.2" ), T( T::number( 30039062.2 )));
+ // long double not supported
+}
+
+void test::strings::valueX::testOUFloat() {
+ testFloat<OUString>();
+}
+
+void test::strings::valueX::testOFloat() {
+ testFloat<OString>();
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/textenc/rtl_tencinfo.cxx b/sal/qa/rtl/textenc/rtl_tencinfo.cxx
new file mode 100644
index 000000000..88da153ae
--- /dev/null
+++ b/sal/qa/rtl/textenc/rtl_tencinfo.cxx
@@ -0,0 +1,1674 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_locales.h>
+
+#include <string.h>
+
+#include <rtl/tencinfo.h>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+namespace
+{
+ class testBestMime : public CppUnit::TestFixture
+ {
+ public:
+ void check(rtl_TextEncoding eIn, rtl_TextEncoding eOut)
+ {
+ const char *pCharSet = rtl_getBestMimeCharsetFromTextEncoding(eIn);
+ rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromMimeCharset(pCharSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("rtl_getBestMimeCharsetFromTextEncoding && rtl_getTextEncodingFromMimeCharset differdiffer", eOut, eTextEnc );
+ }
+
+ // the defines for the follows test could be found in file inc/rtl/textenc.h
+
+ void MimeCharsetFromTextEncoding_MS_1252()
+ {
+ check( RTL_TEXTENCODING_MS_1252, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void MimeCharsetFromTextEncoding_APPLE_ROMAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_ROMAN, RTL_TEXTENCODING_APPLE_ROMAN);
+ }
+
+ void MimeCharsetFromTextEncoding_IBM_437()
+ {
+ check( RTL_TEXTENCODING_IBM_437, RTL_TEXTENCODING_IBM_437 );
+ }
+
+ void MimeCharsetFromTextEncoding_IBM_850()
+ {
+ check( RTL_TEXTENCODING_IBM_850, RTL_TEXTENCODING_IBM_850 );
+ }
+
+ void MimeCharsetFromTextEncoding_IBM_860()
+ {
+ check( RTL_TEXTENCODING_IBM_860, RTL_TEXTENCODING_IBM_860 );
+ }
+
+ void MimeCharsetFromTextEncoding_IBM_861()
+ {
+ check( RTL_TEXTENCODING_IBM_861, RTL_TEXTENCODING_IBM_861 );
+ }
+
+ void MimeCharsetFromTextEncoding_IBM_863()
+ {
+ check( RTL_TEXTENCODING_IBM_863, RTL_TEXTENCODING_IBM_863 );
+ }
+
+ void MimeCharsetFromTextEncoding_IBM_865()
+ {
+ check( RTL_TEXTENCODING_IBM_865, RTL_TEXTENCODING_IBM_865 );
+ }
+
+ void MimeCharsetFromTextEncoding_SYMBOL()
+ {
+ check( RTL_TEXTENCODING_SYMBOL, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void MimeCharsetFromTextEncoding_ASCII_US()
+ {
+ check( RTL_TEXTENCODING_ASCII_US, RTL_TEXTENCODING_ASCII_US );
+ }
+
+ void MimeCharsetFromTextEncoding_ISO_8859_1()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_1, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_2()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_2, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_3()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_3, RTL_TEXTENCODING_ISO_8859_3 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_4()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_4, RTL_TEXTENCODING_ISO_8859_4 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_5()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_5, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_6()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_6, RTL_TEXTENCODING_ISO_8859_6 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_7()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_7, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_8()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_8, RTL_TEXTENCODING_ISO_8859_8 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_9()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_9, RTL_TEXTENCODING_ISO_8859_9 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_14()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_14, RTL_TEXTENCODING_ISO_8859_14 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_15()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_15, RTL_TEXTENCODING_ISO_8859_15 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_737()
+ {
+ check( RTL_TEXTENCODING_IBM_737, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_775()
+ {
+ check( RTL_TEXTENCODING_IBM_775, RTL_TEXTENCODING_ISO_8859_4 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_852()
+ {
+ check( RTL_TEXTENCODING_IBM_852, RTL_TEXTENCODING_IBM_852 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_855()
+ {
+ check( RTL_TEXTENCODING_IBM_855, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_857()
+ {
+ check( RTL_TEXTENCODING_IBM_857, RTL_TEXTENCODING_ISO_8859_9 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_862()
+ {
+ check( RTL_TEXTENCODING_IBM_862, RTL_TEXTENCODING_IBM_862 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_864()
+ {
+ check( RTL_TEXTENCODING_IBM_864, RTL_TEXTENCODING_IBM_864 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_866()
+ {
+ check( RTL_TEXTENCODING_IBM_866, RTL_TEXTENCODING_IBM_866 );
+ }
+ void MimeCharsetFromTextEncoding_IBM_869()
+ {
+ check( RTL_TEXTENCODING_IBM_869, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+ void MimeCharsetFromTextEncoding_MS_874()
+ {
+ check( RTL_TEXTENCODING_MS_874, RTL_TEXTENCODING_MS_874 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1250()
+ {
+ check( RTL_TEXTENCODING_MS_1250, RTL_TEXTENCODING_MS_1250 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1251()
+ {
+ check( RTL_TEXTENCODING_MS_1251, RTL_TEXTENCODING_MS_1251 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1253()
+ {
+ check( RTL_TEXTENCODING_MS_1253, RTL_TEXTENCODING_MS_1253 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1254()
+ {
+ check( RTL_TEXTENCODING_MS_1254, RTL_TEXTENCODING_MS_1254 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1255()
+ {
+ check( RTL_TEXTENCODING_MS_1255, RTL_TEXTENCODING_MS_1255 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1256()
+ {
+ check( RTL_TEXTENCODING_MS_1256, RTL_TEXTENCODING_MS_1256 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1257()
+ {
+ check( RTL_TEXTENCODING_MS_1257, RTL_TEXTENCODING_MS_1257 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1258()
+ {
+ check( RTL_TEXTENCODING_MS_1258, RTL_TEXTENCODING_MS_1258 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_CENTEURO()
+ {
+ check( RTL_TEXTENCODING_APPLE_CENTEURO, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_CROATIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_CROATIAN, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_CYRILLIC()
+ {
+ check( RTL_TEXTENCODING_APPLE_CYRILLIC, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_GREEK()
+ {
+ check( RTL_TEXTENCODING_APPLE_GREEK, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_ICELAND()
+ {
+ check( RTL_TEXTENCODING_APPLE_ICELAND, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_ROMANIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_ROMANIAN, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_TURKISH()
+ {
+ check( RTL_TEXTENCODING_APPLE_TURKISH, RTL_TEXTENCODING_ISO_8859_9 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_UKRAINIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_UKRAINIAN, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+ void MimeCharsetFromTextEncoding_MS_932()
+ {
+ check( RTL_TEXTENCODING_MS_932, RTL_TEXTENCODING_SHIFT_JIS );
+ }
+ void MimeCharsetFromTextEncoding_MS_936()
+ {
+ check( RTL_TEXTENCODING_MS_936, RTL_TEXTENCODING_GB_2312 );
+ }
+ void MimeCharsetFromTextEncoding_MS_949()
+ {
+ check( RTL_TEXTENCODING_MS_949, RTL_TEXTENCODING_EUC_KR );
+ }
+ void MimeCharsetFromTextEncoding_MS_950()
+ {
+ check( RTL_TEXTENCODING_MS_950, RTL_TEXTENCODING_BIG5 );
+ }
+ void MimeCharsetFromTextEncoding_KOI8_R()
+ {
+ check( RTL_TEXTENCODING_KOI8_R, RTL_TEXTENCODING_KOI8_R );
+ }
+ void MimeCharsetFromTextEncoding_UTF7()
+ {
+ check( RTL_TEXTENCODING_UTF7, RTL_TEXTENCODING_UTF7 );
+ }
+ void MimeCharsetFromTextEncoding_UTF8()
+ {
+ check( RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_UTF8 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_10()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_10, RTL_TEXTENCODING_ISO_8859_10 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_8859_13()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_13, RTL_TEXTENCODING_ISO_8859_13 );
+ }
+ void MimeCharsetFromTextEncoding_MS_1361()
+ {
+ check( RTL_TEXTENCODING_MS_1361, RTL_TEXTENCODING_EUC_KR );
+ }
+ void MimeCharsetFromTextEncoding_TIS_620()
+ {
+ check( RTL_TEXTENCODING_TIS_620, RTL_TEXTENCODING_TIS_620 );
+ }
+ void MimeCharsetFromTextEncoding_KOI8_U()
+ {
+ check( RTL_TEXTENCODING_KOI8_U, RTL_TEXTENCODING_KOI8_U );
+ }
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ void MimeCharsetFromTextEncoding_APPLE_JAPANESE()
+ {
+ check( RTL_TEXTENCODING_APPLE_JAPANESE, RTL_TEXTENCODING_SHIFT_JIS );
+ }
+ void MimeCharsetFromTextEncoding_SHIFT_JIS()
+ {
+ check( RTL_TEXTENCODING_SHIFT_JIS, RTL_TEXTENCODING_SHIFT_JIS );
+ }
+ void MimeCharsetFromTextEncoding_EUC_JP()
+ {
+ check( RTL_TEXTENCODING_EUC_JP, RTL_TEXTENCODING_EUC_JP );
+ }
+ void MimeCharsetFromTextEncoding_ISO_2022_JP()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_JP, RTL_TEXTENCODING_ISO_2022_JP );
+ }
+ void MimeCharsetFromTextEncoding_JIS_X_0201()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0201, RTL_TEXTENCODING_EUC_JP );
+ }
+ void MimeCharsetFromTextEncoding_JIS_X_0208()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0208, RTL_TEXTENCODING_EUC_JP );
+ }
+ void MimeCharsetFromTextEncoding_JIS_X_0212()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0212, RTL_TEXTENCODING_EUC_JP );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ void MimeCharsetFromTextEncoding_APPLE_KOREAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_KOREAN, RTL_TEXTENCODING_EUC_KR );
+ }
+ void MimeCharsetFromTextEncoding_EUC_KR()
+ {
+ check( RTL_TEXTENCODING_EUC_KR, RTL_TEXTENCODING_EUC_KR );
+ }
+ void MimeCharsetFromTextEncoding_ISO_2022_KR()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_KR, RTL_TEXTENCODING_ISO_2022_KR );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ void MimeCharsetFromTextEncoding_APPLE_CHINSIMP()
+ {
+ check( RTL_TEXTENCODING_APPLE_CHINSIMP, RTL_TEXTENCODING_GB_2312 );
+ }
+ void MimeCharsetFromTextEncoding_APPLE_CHINTRAD()
+ {
+ check( RTL_TEXTENCODING_APPLE_CHINTRAD, RTL_TEXTENCODING_BIG5 );
+ }
+ void MimeCharsetFromTextEncoding_GB_2312()
+ {
+ check( RTL_TEXTENCODING_GB_2312, RTL_TEXTENCODING_GB_2312 );
+ }
+ void MimeCharsetFromTextEncoding_GBT_12345()
+ {
+ check( RTL_TEXTENCODING_GBT_12345, RTL_TEXTENCODING_GBT_12345 );
+ }
+ void MimeCharsetFromTextEncoding_GBK()
+ {
+ check( RTL_TEXTENCODING_GBK, RTL_TEXTENCODING_GBK );
+ }
+ void MimeCharsetFromTextEncoding_BIG5()
+ {
+ check( RTL_TEXTENCODING_BIG5, RTL_TEXTENCODING_BIG5 );
+ }
+ void MimeCharsetFromTextEncoding_EUC_CN()
+ {
+ check( RTL_TEXTENCODING_EUC_CN, RTL_TEXTENCODING_GB_2312 );
+ }
+ void MimeCharsetFromTextEncoding_EUC_TW()
+ {
+ check( RTL_TEXTENCODING_EUC_TW, RTL_TEXTENCODING_BIG5 );
+ }
+ void MimeCharsetFromTextEncoding_ISO_2022_CN()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_CN, RTL_TEXTENCODING_ISO_2022_CN );
+ }
+ void MimeCharsetFromTextEncoding_GB_18030()
+ {
+ check( RTL_TEXTENCODING_GB_18030, RTL_TEXTENCODING_GB_18030 );
+ }
+ void MimeCharsetFromTextEncoding_BIG5_HKSCS()
+ {
+ check( RTL_TEXTENCODING_BIG5_HKSCS, RTL_TEXTENCODING_BIG5_HKSCS );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_FOR_SCRIPT_Deva
+ void MimeCharsetFromTextEncoding_ISCII_DEVANAGARI()
+ {
+ check( RTL_TEXTENCODING_ISCII_DEVANAGARI, RTL_TEXTENCODING_ISCII_DEVANAGARI );
+ }
+#endif
+ CPPUNIT_TEST_SUITE( testBestMime );
+
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1252 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_ROMAN );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_437 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_850 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_860 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_861 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_863 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_865 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_SYMBOL );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ASCII_US );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_1 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_2 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_3 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_4 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_5 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_6 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_7 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_8 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_9 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_14 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_15 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_737 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_775 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_852 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_855 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_857 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_862 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_864 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_866 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_IBM_869 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_874 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1250 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1251 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1253 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1254 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1255 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1256 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1257 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1258 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_CENTEURO );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_CROATIAN );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_CYRILLIC );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_GREEK );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_ICELAND );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_ROMANIAN );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_TURKISH );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_UKRAINIAN );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_932 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_936 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_949 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_950 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_KOI8_R );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_UTF7 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_UTF8 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_10 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_8859_13 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_MS_1361 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_TIS_620 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_KOI8_U );
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_JAPANESE );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_SHIFT_JIS );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_EUC_JP );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_2022_JP );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_JIS_X_0201 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_JIS_X_0208 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_JIS_X_0212 );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_KOREAN );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_EUC_KR );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_2022_KR );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_CHINSIMP );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_APPLE_CHINTRAD );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_GB_2312 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_GBT_12345 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_GBK );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_BIG5 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_EUC_CN );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_EUC_TW );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISO_2022_CN );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_GB_18030 );
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_BIG5_HKSCS );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_FOR_SCRIPT_Deva
+ CPPUNIT_TEST( MimeCharsetFromTextEncoding_ISCII_DEVANAGARI );
+#endif
+ CPPUNIT_TEST_SUITE_END( );
+ };
+
+ class testBestUnix : public CppUnit::TestFixture
+ {
+ public:
+ void check(rtl_TextEncoding eIn, rtl_TextEncoding eOut)
+ {
+ const char *pCharSet = rtl_getBestUnixCharsetFromTextEncoding(eIn);
+ rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromUnixCharset(pCharSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("rtl_getBestUnixCharsetFromTextEncoding && rtl_getTextEncodingFromUnixCharset", eOut, eTextEnc );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1252()
+ {
+ check( RTL_TEXTENCODING_MS_1252, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_ROMAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_ROMAN, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_437()
+ {
+ check( RTL_TEXTENCODING_IBM_437, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_850()
+ {
+ check( RTL_TEXTENCODING_IBM_850, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_860()
+ {
+ check( RTL_TEXTENCODING_IBM_860, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_861()
+ {
+ check( RTL_TEXTENCODING_IBM_861, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_863()
+ {
+ check( RTL_TEXTENCODING_IBM_863, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_865()
+ {
+ check( RTL_TEXTENCODING_IBM_865, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_SYMBOL()
+ {
+ check( RTL_TEXTENCODING_SYMBOL, RTL_TEXTENCODING_SYMBOL );
+ }
+
+ void UnixCharsetFromTextEncoding_ASCII_US()
+ {
+ check( RTL_TEXTENCODING_ASCII_US, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_1()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_1, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_2()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_2, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_3()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_3, RTL_TEXTENCODING_ISO_8859_3 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_4()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_4, RTL_TEXTENCODING_ISO_8859_4 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_5()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_5, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_6()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_6, RTL_TEXTENCODING_ISO_8859_6 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_7()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_7, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_8()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_8, RTL_TEXTENCODING_ISO_8859_8 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_9()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_9, RTL_TEXTENCODING_ISO_8859_9 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_14()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_14, RTL_TEXTENCODING_ISO_8859_14 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_15()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_15, RTL_TEXTENCODING_ISO_8859_15 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_737()
+ {
+ check( RTL_TEXTENCODING_IBM_737, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_775()
+ {
+ check( RTL_TEXTENCODING_IBM_775, RTL_TEXTENCODING_ISO_8859_4 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_852()
+ {
+ check( RTL_TEXTENCODING_IBM_852, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_855()
+ {
+ check( RTL_TEXTENCODING_IBM_855, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_857()
+ {
+ check( RTL_TEXTENCODING_IBM_857, RTL_TEXTENCODING_ISO_8859_9 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_862()
+ {
+ check( RTL_TEXTENCODING_IBM_862, RTL_TEXTENCODING_ISO_8859_8 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_864()
+ {
+ check( RTL_TEXTENCODING_IBM_864, RTL_TEXTENCODING_ISO_8859_6 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_866()
+ {
+ check( RTL_TEXTENCODING_IBM_866, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+
+ void UnixCharsetFromTextEncoding_IBM_869()
+ {
+ check( RTL_TEXTENCODING_IBM_869, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_874()
+ {
+ check( RTL_TEXTENCODING_MS_874, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1250()
+ {
+ check( RTL_TEXTENCODING_MS_1250, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1251()
+ {
+ check( RTL_TEXTENCODING_MS_1251, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1253()
+ {
+ check( RTL_TEXTENCODING_MS_1253, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1254()
+ {
+ check( RTL_TEXTENCODING_MS_1254, RTL_TEXTENCODING_ISO_8859_9 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1255()
+ {
+ check( RTL_TEXTENCODING_MS_1255, RTL_TEXTENCODING_ISO_8859_8 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1256()
+ {
+ check( RTL_TEXTENCODING_MS_1256, RTL_TEXTENCODING_ISO_8859_6 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1257()
+ {
+ check( RTL_TEXTENCODING_MS_1257, RTL_TEXTENCODING_ISO_8859_4 );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_1258()
+ {
+ check( RTL_TEXTENCODING_MS_1258, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_CENTEURO()
+ {
+ check( RTL_TEXTENCODING_APPLE_CENTEURO, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_CROATIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_CROATIAN, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_CYRILLIC()
+ {
+ check( RTL_TEXTENCODING_APPLE_CYRILLIC, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_GREEK()
+ {
+ check( RTL_TEXTENCODING_APPLE_GREEK, RTL_TEXTENCODING_ISO_8859_7 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_ICELAND()
+ {
+ check( RTL_TEXTENCODING_APPLE_ICELAND, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_ROMANIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_ROMANIAN, RTL_TEXTENCODING_ISO_8859_2 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_TURKISH()
+ {
+ check( RTL_TEXTENCODING_APPLE_TURKISH, RTL_TEXTENCODING_ISO_8859_9 );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_UKRAINIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_UKRAINIAN, RTL_TEXTENCODING_ISO_8859_5 );
+ }
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ void UnixCharsetFromTextEncoding_APPLE_CHINSIMP()
+ {
+ check( RTL_TEXTENCODING_APPLE_CHINSIMP, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_APPLE_CHINTRAD()
+ {
+ check( RTL_TEXTENCODING_APPLE_CHINTRAD, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ void UnixCharsetFromTextEncoding_APPLE_JAPANESE()
+ {
+ check( RTL_TEXTENCODING_APPLE_JAPANESE, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ void UnixCharsetFromTextEncoding_APPLE_KOREAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_KOREAN, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+ void UnixCharsetFromTextEncoding_MS_932()
+ {
+ check( RTL_TEXTENCODING_MS_932, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_936()
+ {
+ check( RTL_TEXTENCODING_MS_936, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_949()
+ {
+ check( RTL_TEXTENCODING_MS_949, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_MS_950()
+ {
+ check( RTL_TEXTENCODING_MS_950, RTL_TEXTENCODING_DONTKNOW );
+ }
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ void UnixCharsetFromTextEncoding_SHIFT_JIS()
+ {
+ check( RTL_TEXTENCODING_SHIFT_JIS, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ void UnixCharsetFromTextEncoding_GB_2312()
+ {
+ check( RTL_TEXTENCODING_GB_2312, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_GBT_12345()
+ {
+ check( RTL_TEXTENCODING_GBT_12345, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_GBK()
+ {
+ check( RTL_TEXTENCODING_GBK, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_BIG5()
+ {
+ check( RTL_TEXTENCODING_BIG5, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ void UnixCharsetFromTextEncoding_EUC_JP()
+ {
+ check( RTL_TEXTENCODING_EUC_JP, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ void UnixCharsetFromTextEncoding_EUC_CN()
+ {
+ check( RTL_TEXTENCODING_EUC_CN, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_EUC_TW()
+ {
+ check( RTL_TEXTENCODING_EUC_TW, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ void UnixCharsetFromTextEncoding_ISO_2022_JP()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_JP, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ void UnixCharsetFromTextEncoding_ISO_2022_CN()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_CN, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+ void UnixCharsetFromTextEncoding_KOI8_R()
+ {
+ check( RTL_TEXTENCODING_KOI8_R, RTL_TEXTENCODING_KOI8_R );
+ }
+
+ void UnixCharsetFromTextEncoding_UTF7()
+ {
+ check( RTL_TEXTENCODING_UTF7, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_UTF8()
+ {
+ check( RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_10()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_10, RTL_TEXTENCODING_ISO_8859_10 );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_8859_13()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_13, RTL_TEXTENCODING_ISO_8859_13 );
+ }
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ void UnixCharsetFromTextEncoding_EUC_KR()
+ {
+ check( RTL_TEXTENCODING_EUC_KR, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_ISO_2022_KR()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_KR, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ void UnixCharsetFromTextEncoding_JIS_X_0201()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0201, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_JIS_X_0208()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0208, RTL_TEXTENCODING_DONTKNOW );
+ }
+
+ void UnixCharsetFromTextEncoding_JIS_X_0212()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0212, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+ void UnixCharsetFromTextEncoding_MS_1361()
+ {
+ check( RTL_TEXTENCODING_MS_1361, RTL_TEXTENCODING_DONTKNOW );
+ }
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ void UnixCharsetFromTextEncoding_GB_18030()
+ {
+ check( RTL_TEXTENCODING_GB_18030, RTL_TEXTENCODING_GBK );
+ }
+
+ void UnixCharsetFromTextEncoding_BIG5_HKSCS()
+ {
+ check( RTL_TEXTENCODING_BIG5_HKSCS, RTL_TEXTENCODING_DONTKNOW );
+ }
+#endif
+ void UnixCharsetFromTextEncoding_TIS_620()
+ {
+ check( RTL_TEXTENCODING_TIS_620, RTL_TEXTENCODING_ISO_8859_1 );
+ }
+
+ void UnixCharsetFromTextEncoding_KOI8_U()
+ {
+ check( RTL_TEXTENCODING_KOI8_U, RTL_TEXTENCODING_KOI8_U );
+ }
+
+ CPPUNIT_TEST_SUITE( testBestUnix );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1252 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_ROMAN );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_437 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_850 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_860 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_861 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_863 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_865 );
+
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_SYMBOL );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ASCII_US );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_1 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_2 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_3 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_4 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_5 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_6 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_7 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_8 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_9 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_14 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_15 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_737 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_775 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_852 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_855 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_857 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_862 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_864 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_866 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_IBM_869 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_874 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1250 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1251 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1253 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1254 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1255 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1256 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1257 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1258 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_CENTEURO );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_CROATIAN );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_CYRILLIC );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_GREEK );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_ICELAND );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_ROMANIAN );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_TURKISH );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_UKRAINIAN );
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_CHINSIMP );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_CHINTRAD );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_JAPANESE );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_APPLE_KOREAN );
+#endif
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_932 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_936 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_949 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_950 );
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_SHIFT_JIS );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_GB_2312 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_GBT_12345 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_GBK );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_BIG5 );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_EUC_JP );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_EUC_CN );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_EUC_TW );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_2022_JP );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_2022_CN );
+#endif
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_KOI8_R );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_UTF7 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_UTF8 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_10 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_8859_13 );
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_EUC_KR );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_ISO_2022_KR );
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_JIS_X_0201 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_JIS_X_0208 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_JIS_X_0212 );
+#endif
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_MS_1361 );
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_GB_18030 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_BIG5_HKSCS );
+#endif
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_TIS_620 );
+ CPPUNIT_TEST( UnixCharsetFromTextEncoding_KOI8_U );
+
+ CPPUNIT_TEST_SUITE_END( );
+ };
+
+ class testBestWindows : public CppUnit::TestFixture
+ {
+ public:
+ void check(rtl_TextEncoding nIn, rtl_TextEncoding nOut)
+ {
+ const sal_uInt8 nCharSet = rtl_getBestWindowsCharsetFromTextEncoding(nIn);
+ rtl_TextEncoding eTextEnc = rtl_getTextEncodingFromWindowsCharset(nCharSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("rtl_getBestWindowsCharsetFromTextEncoding && rtl_getTextEncodingFromWindowsCharset differ", nOut, eTextEnc );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1252()
+ {
+ check( RTL_TEXTENCODING_MS_1252, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_ROMAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_ROMAN, RTL_TEXTENCODING_APPLE_ROMAN );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_437()
+ {
+ check( RTL_TEXTENCODING_IBM_437, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_850()
+ {
+ check( RTL_TEXTENCODING_IBM_850, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_860()
+ {
+ check( RTL_TEXTENCODING_IBM_860, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_861()
+ {
+ check( RTL_TEXTENCODING_IBM_861, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_863()
+ {
+ check( RTL_TEXTENCODING_IBM_863, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_865()
+ {
+ check( RTL_TEXTENCODING_IBM_865, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_SYMBOL()
+ {
+ check( RTL_TEXTENCODING_SYMBOL, RTL_TEXTENCODING_SYMBOL );
+ }
+
+ void WindowsCharsetFromTextEncoding_ASCII_US()
+ {
+ check( RTL_TEXTENCODING_ASCII_US, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_1()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_1, RTL_TEXTENCODING_MS_1252 );
+ }
+#if 0
+ void WindowsCharsetFromTextEncoding_ISO_8859_2()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_2, RTL_TEXTENCODING_MS_1252 );
+ }
+#endif
+ void WindowsCharsetFromTextEncoding_ISO_8859_3()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_3, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_4()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_4, RTL_TEXTENCODING_MS_1257 );
+ }
+#if 0
+ void WindowsCharsetFromTextEncoding_ISO_8859_5()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_5, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_6()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_6, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_7()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_7, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_8()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_8, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_9()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_9, RTL_TEXTENCODING_MS_1252 );
+ }
+#endif
+ void WindowsCharsetFromTextEncoding_ISO_8859_14()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_14, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_15()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_15, RTL_TEXTENCODING_MS_1252 );
+ }
+#if 0
+ void WindowsCharsetFromTextEncoding_IBM_737()
+ {
+ check( RTL_TEXTENCODING_IBM_737, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_775()
+ {
+ check( RTL_TEXTENCODING_IBM_775, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_852()
+ {
+ check( RTL_TEXTENCODING_IBM_852, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_855()
+ {
+ check( RTL_TEXTENCODING_IBM_855, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_857()
+ {
+ check( RTL_TEXTENCODING_IBM_857, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_862()
+ {
+ check( RTL_TEXTENCODING_IBM_862, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_864()
+ {
+ check( RTL_TEXTENCODING_IBM_864, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_866()
+ {
+ check( RTL_TEXTENCODING_IBM_866, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_IBM_869()
+ {
+ check( RTL_TEXTENCODING_IBM_869, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_874()
+ {
+ check( RTL_TEXTENCODING_MS_874, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1250()
+ {
+ check( RTL_TEXTENCODING_MS_1250, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1251()
+ {
+ check( RTL_TEXTENCODING_MS_1251, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1253()
+ {
+ check( RTL_TEXTENCODING_MS_1253, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1254()
+ {
+ check( RTL_TEXTENCODING_MS_1254, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1255()
+ {
+ check( RTL_TEXTENCODING_MS_1255, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1256()
+ {
+ check( RTL_TEXTENCODING_MS_1256, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1257()
+ {
+ check( RTL_TEXTENCODING_MS_1257, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1258()
+ {
+ check( RTL_TEXTENCODING_MS_1258, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_ARABIC()
+ {
+ check( RTL_TEXTENCODING_APPLE_ARABIC, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_CENTEURO()
+ {
+ check( RTL_TEXTENCODING_APPLE_CENTEURO, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_CROATIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_CROATIAN, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_CYRILLIC()
+ {
+ check( RTL_TEXTENCODING_APPLE_CYRILLIC, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_DEVANAGARI()
+ {
+ check( RTL_TEXTENCODING_APPLE_DEVANAGARI, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_FARSI()
+ {
+ check( RTL_TEXTENCODING_APPLE_FARSI, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_GREEK()
+ {
+ check( RTL_TEXTENCODING_APPLE_GREEK, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_GUJARATI()
+ {
+ check( RTL_TEXTENCODING_APPLE_GUJARATI, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_GURMUKHI()
+ {
+ check( RTL_TEXTENCODING_APPLE_GURMUKHI, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_HEBREW()
+ {
+ check( RTL_TEXTENCODING_APPLE_HEBREW, RTL_TEXTENCODING_MS_1252 );
+ }
+#endif
+ void WindowsCharsetFromTextEncoding_APPLE_ICELAND()
+ {
+ check( RTL_TEXTENCODING_APPLE_ICELAND, RTL_TEXTENCODING_MS_1252 );
+ }
+#if 0
+ void WindowsCharsetFromTextEncoding_APPLE_ROMANIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_ROMANIAN, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_THAI()
+ {
+ check( RTL_TEXTENCODING_APPLE_THAI, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_TURKISH()
+ {
+ check( RTL_TEXTENCODING_APPLE_TURKISH, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_UKRAINIAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_UKRAINIAN, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_CHINSIMP()
+ {
+ check( RTL_TEXTENCODING_APPLE_CHINSIMP, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_CHINTRAD()
+ {
+ check( RTL_TEXTENCODING_APPLE_CHINTRAD, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_JAPANESE()
+ {
+ check( RTL_TEXTENCODING_APPLE_JAPANESE, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_APPLE_KOREAN()
+ {
+ check( RTL_TEXTENCODING_APPLE_KOREAN, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_932()
+ {
+ check( RTL_TEXTENCODING_MS_932, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_936()
+ {
+ check( RTL_TEXTENCODING_MS_936, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_949()
+ {
+ check( RTL_TEXTENCODING_MS_949, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_950()
+ {
+ check( RTL_TEXTENCODING_MS_950, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_SHIFT_JIS()
+ {
+ check( RTL_TEXTENCODING_SHIFT_JIS, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_GB_2312()
+ {
+ check( RTL_TEXTENCODING_GB_2312, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_GBT_12345()
+ {
+ check( RTL_TEXTENCODING_GBT_12345, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_GBK()
+ {
+ check( RTL_TEXTENCODING_GBK, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_BIG5()
+ {
+ check( RTL_TEXTENCODING_BIG5, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_EUC_JP()
+ {
+ check( RTL_TEXTENCODING_EUC_JP, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_EUC_CN()
+ {
+ check( RTL_TEXTENCODING_EUC_CN, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_EUC_TW()
+ {
+ check( RTL_TEXTENCODING_EUC_TW, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_2022_JP()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_JP, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_2022_CN()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_CN, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_KOI8_R()
+ {
+ check( RTL_TEXTENCODING_KOI8_R, RTL_TEXTENCODING_MS_1252 );
+ }
+#endif
+ void WindowsCharsetFromTextEncoding_UTF7()
+ {
+ check( RTL_TEXTENCODING_UTF7, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_UTF8()
+ {
+ check( RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 );
+ }
+#if 0
+ void WindowsCharsetFromTextEncoding_ISO_8859_10()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_10, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_8859_13()
+ {
+ check( RTL_TEXTENCODING_ISO_8859_13, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_EUC_KR()
+ {
+ check( RTL_TEXTENCODING_EUC_KR, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISO_2022_KR()
+ {
+ check( RTL_TEXTENCODING_ISO_2022_KR, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_JIS_X_0201()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0201, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_JIS_X_0208()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0208, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_JIS_X_0212()
+ {
+ check( RTL_TEXTENCODING_JIS_X_0212, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_MS_1361()
+ {
+ check( RTL_TEXTENCODING_MS_1361, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_GB_18030()
+ {
+ check( RTL_TEXTENCODING_GB_18030, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_BIG5_HKSCS()
+ {
+ check( RTL_TEXTENCODING_BIG5_HKSCS, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_TIS_620()
+ {
+ check( RTL_TEXTENCODING_TIS_620, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_KOI8_U()
+ {
+ check( RTL_TEXTENCODING_KOI8_U, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ void WindowsCharsetFromTextEncoding_ISCII_DEVANAGARI()
+ {
+ check( RTL_TEXTENCODING_ISCII_DEVANAGARI, RTL_TEXTENCODING_MS_1252 );
+ }
+#endif
+ void WindowsCharsetFromTextEncoding_JAVA_UTF8()
+ {
+ check( RTL_TEXTENCODING_JAVA_UTF8, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ CPPUNIT_TEST_SUITE( testBestWindows );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1252 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_ROMAN );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_437 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_850 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_860 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_861 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_863 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_865 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_SYMBOL );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ASCII_US );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_1 );
+#if 0
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_2 );
+#endif
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_3 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_4 );
+#if 0
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_5 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_6 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_7 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_8 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_9 );
+#endif
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_14 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_15 );
+#if 0
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_737 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_775 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_852 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_855 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_857 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_862 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_864 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_866 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_IBM_869 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_874 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1250 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1251 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1253 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1254 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1255 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1256 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1257 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1258 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_ARABIC );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_CENTEURO );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_CROATIAN );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_CYRILLIC );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_DEVANAGARI );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_FARSI );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_GREEK );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_GUJARATI );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_GURMUKHI );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_HEBREW );
+#endif
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_ICELAND );
+#if 0
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_ROMANIAN );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_THAI );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_TURKISH );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_UKRAINIAN );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_CHINSIMP );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_CHINTRAD );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_JAPANESE );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_APPLE_KOREAN );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_932 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_936 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_949 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_950 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_SHIFT_JIS );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_GB_2312 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_GBT_12345 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_GBK );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_BIG5 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_EUC_JP );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_EUC_CN );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_EUC_TW );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_2022_JP );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_2022_CN );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_KOI8_R );
+#endif
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_UTF7 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_UTF8 );
+#if 0
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_10 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_8859_13 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_EUC_KR );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISO_2022_KR );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_JIS_X_0201 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_JIS_X_0208 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_JIS_X_0212 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_MS_1361 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_GB_18030 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_BIG5_HKSCS );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_TIS_620 );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_KOI8_U );
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_ISCII_DEVANAGARI );
+#endif
+ CPPUNIT_TEST( WindowsCharsetFromTextEncoding_JAVA_UTF8 );
+
+ CPPUNIT_TEST_SUITE_END( );
+ };
+
+ class testTextEncodingInfo: public CppUnit::TestFixture
+ {
+ public:
+ // not implemented encoding test
+ void testTextEncodingInfo_001()
+ {
+ rtl_TextEncodingInfo aInfo1, aInfo2, aInfo3, aInfo4, aInfo5;
+ aInfo1.StructSize = 4;
+ // not implemented
+ bool bRes1 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_ARABIC, &aInfo1 );
+ // implemented
+ bool bRes11 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_CYRILLIC, &aInfo1 );
+ CPPUNIT_ASSERT_MESSAGE("should return sal_False.", !bRes1);
+ CPPUNIT_ASSERT_MESSAGE("should return sal_False.", !bRes11);
+
+ aInfo2.StructSize = 5;
+ bool bRes2 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_ARABIC, &aInfo2 );
+ bool bRes21 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_CYRILLIC, &aInfo2 );
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", bRes2);
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", bRes21);
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", aInfo2.MinimumCharSize >=1 );
+
+ aInfo3.StructSize = 6;
+ bool bRes3 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_ARABIC, &aInfo3 );
+ bool bRes31 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_CYRILLIC, &aInfo3 );
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", bRes3);
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", bRes31);
+//&& aInfo2.MinimumCharSize >=1 );
+
+ aInfo4.StructSize = 8;
+ bool bRes4 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_ARABIC, &aInfo4 );
+ bool bRes41 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_CYRILLIC, &aInfo4);
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", bRes4);
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", bRes41);
+// && aInfo2.MinimumCharSize >=1 );
+
+ aInfo5.StructSize = sizeof aInfo5;
+ bool bRes5 = rtl_getTextEncodingInfo( RTL_TEXTENCODING_APPLE_ARABIC, &aInfo5 );
+ CPPUNIT_ASSERT_MESSAGE("StructSize<6 should return sal_True", !bRes5);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "StructSize<6 should return sal_True", sal_uInt32(0), aInfo5.Flags);
+
+ }
+ CPPUNIT_TEST_SUITE(testTextEncodingInfo);
+ CPPUNIT_TEST(testTextEncodingInfo_001);
+ CPPUNIT_TEST_SUITE_END();
+ };
+
+ class testEncodingFromUnix: public CppUnit::TestFixture
+ {
+ public:
+ void testIso8859() {
+ check(RTL_TEXTENCODING_DONTKNOW, "ISO8859");
+ check(RTL_TEXTENCODING_DONTKNOW, "ISO8859-0");
+ check(RTL_TEXTENCODING_DONTKNOW, "ISO8859-01");
+ check(RTL_TEXTENCODING_DONTKNOW, "ISO8859_1");
+ check(RTL_TEXTENCODING_DONTKNOW, "ISO88591");
+ check(RTL_TEXTENCODING_ISO_8859_1, "ISO8859-1");
+ check(RTL_TEXTENCODING_ISO_8859_2, "ISO8859-2");
+ check(RTL_TEXTENCODING_ISO_8859_3, "ISO8859-3");
+ check(RTL_TEXTENCODING_ISO_8859_4, "ISO8859-4");
+ check(RTL_TEXTENCODING_ISO_8859_5, "ISO8859-5");
+ check(RTL_TEXTENCODING_ISO_8859_6, "ISO8859-6");
+ check(RTL_TEXTENCODING_ISO_8859_7, "ISO8859-7");
+ check(RTL_TEXTENCODING_ISO_8859_8, "ISO8859-8");
+ check(RTL_TEXTENCODING_ISO_8859_9, "ISO8859-9");
+ check(RTL_TEXTENCODING_ISO_8859_10, "ISO8859-10");
+ check(RTL_TEXTENCODING_TIS_620, "ISO8859-11");
+ check(RTL_TEXTENCODING_ISO_8859_13, "ISO8859-13");
+ check(RTL_TEXTENCODING_ISO_8859_14, "ISO8859-14");
+ check(RTL_TEXTENCODING_ISO_8859_15, "ISO8859-15");
+ }
+
+ void testTis620() {
+ check(RTL_TEXTENCODING_DONTKNOW, "TIS620");
+ check(RTL_TEXTENCODING_TIS_620, "TIS620-0");
+ check(RTL_TEXTENCODING_DONTKNOW, "TIS620-1");
+ check(RTL_TEXTENCODING_TIS_620, "TIS620-2529");
+ check(RTL_TEXTENCODING_TIS_620, "TIS620-2533");
+ check(RTL_TEXTENCODING_DONTKNOW, "TIS620.2529-0");
+ check(RTL_TEXTENCODING_TIS_620, "TIS620.2529-1");
+ check(RTL_TEXTENCODING_DONTKNOW, "TIS620.2529-2");
+ check(RTL_TEXTENCODING_TIS_620, "TIS620.2533-0");
+ check(RTL_TEXTENCODING_TIS_620, "TIS620.2533-1");
+ check(RTL_TEXTENCODING_DONTKNOW, "TIS620.2533-2");
+ }
+
+ CPPUNIT_TEST_SUITE(testEncodingFromUnix);
+ CPPUNIT_TEST(testIso8859);
+ CPPUNIT_TEST(testTis620);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void check(rtl_TextEncoding expected, char const * input) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ input, expected, rtl_getTextEncodingFromUnixCharset(input));
+ }
+ };
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(testBestMime);
+CPPUNIT_TEST_SUITE_REGISTRATION(testBestUnix);
+CPPUNIT_TEST_SUITE_REGISTRATION(testBestWindows);
+CPPUNIT_TEST_SUITE_REGISTRATION(testTextEncodingInfo);
+CPPUNIT_TEST_SUITE_REGISTRATION(testEncodingFromUnix);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/textenc/rtl_textcvt.cxx b/sal/qa/rtl/textenc/rtl_textcvt.cxx
new file mode 100644
index 000000000..55804bd32
--- /dev/null
+++ b/sal/qa/rtl/textenc/rtl_textcvt.cxx
@@ -0,0 +1,3313 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_locales.h>
+
+#include <sal/config.h>
+
+#include <cstddef>
+#include <cstring>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <o3tl/cppunittraitshelper.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/tencinfo.h>
+#include <rtl/textcvt.h>
+#include <rtl/textenc.h>
+#include <sal/types.h>
+#include <sal/macros.h>
+#include <osl/diagnose.h>
+
+namespace {
+
+struct SingleByteCharSet {
+ rtl_TextEncoding m_nEncoding;
+ sal_Unicode m_aMap[256];
+};
+
+void testSingleByteCharSet(SingleByteCharSet const & rSet) {
+ char aText[256];
+ sal_Unicode aUnicode[256];
+ sal_Size nNumber = 0;
+ for (int i = 0; i < 256; ++i) {
+ if (rSet.m_aMap[i] != 0xFFFF) {
+ aText[nNumber++] = static_cast< char >(i);
+ }
+ }
+ {
+ rtl_TextToUnicodeConverter aConverter
+ = rtl_createTextToUnicodeConverter(rSet.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::number(rSet.m_nEncoding) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ rtl_TextToUnicodeContext aContext
+ = rtl_createTextToUnicodeContext(aConverter);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeContext failed", aContext != nullptr);
+ sal_Size nSize;
+ sal_uInt32 nInfo;
+ sal_Size nConverted;
+ nSize = rtl_convertTextToUnicode(
+ aConverter, aContext, aText, nNumber, aUnicode, nNumber,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR),
+ &nInfo, &nConverted);
+ CPPUNIT_ASSERT_EQUAL(nNumber, nSize);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), nInfo);
+ CPPUNIT_ASSERT_EQUAL(nNumber, nConverted);
+ rtl_destroyTextToUnicodeContext(aConverter, aContext);
+ rtl_destroyTextToUnicodeConverter(aConverter);
+ }
+ {
+ int j = 0;
+ for (int i = 0; i < 256; ++i) {
+ if (rSet.m_aMap[i] != 0xFFFF && aUnicode[j] != rSet.m_aMap[i]) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("rSet.m_aMap[" + OUString::number(i) + "] == " +
+ OUString::number(rSet.m_aMap[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ u'\xFFFF', rSet.m_aMap[i]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("aUnicode[" + OUString::number(j) + "] == " +
+ OUString::number(aUnicode[j], 16) +
+ ", rSet.m_aMap[" + OUString::number(i) + "] == " +
+ OUString::number(rSet.m_aMap[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ rSet.m_aMap[i], aUnicode[j]);
+ }
+ if (rSet.m_aMap[i] != 0xFFFF)
+ j++;
+ }
+ }
+ if (rSet.m_nEncoding == RTL_TEXTENCODING_ASCII_US) {
+ nNumber = 128;
+ }
+ {
+ rtl_UnicodeToTextConverter aConverter
+ = rtl_createUnicodeToTextConverter(rSet.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::createFromAscii(rtl_getMimeCharsetFromTextEncoding(rSet.m_nEncoding)) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ rtl_UnicodeToTextContext aContext
+ = rtl_createUnicodeToTextContext(aConverter);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeContext failed", aContext != nullptr);
+ sal_Size nSize;
+ sal_uInt32 nInfo;
+ sal_Size nConverted;
+ nSize = rtl_convertUnicodeToText(
+ aConverter, aContext, aUnicode, nNumber, aText, nNumber,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR),
+ &nInfo, &nConverted);
+ CPPUNIT_ASSERT_EQUAL(nNumber, nSize);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), nInfo);
+ CPPUNIT_ASSERT_EQUAL(nNumber, nConverted);
+ rtl_destroyUnicodeToTextContext(aConverter, aContext);
+ rtl_destroyUnicodeToTextConverter(aConverter);
+ }
+ {
+ int j = 0;
+ for (int i = 0; i < 256; ++i) {
+ if (rSet.m_aMap[i] != 0xFFFF
+ && aText[j] != static_cast< char >(i))
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("rSet.m_aMap[" + OUString::number(i) + "] == " +
+ OUString::number(rSet.m_aMap[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ u'\xFFFF', rSet.m_aMap[i]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("aText[" + OUString::number(j) + "] == " +
+ OUString::number(i, 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ static_cast< char >(i), aText[j]);
+ }
+ if (rSet.m_aMap[i] != 0xFFFF)
+ j++;
+ }
+ }
+ for (int i = 0; i < 256; ++i) {
+ if (rSet.m_aMap[i] == 0xFFFF) {
+ aText[0] = static_cast< char >(i);
+ rtl_TextToUnicodeConverter aConverter
+ = rtl_createTextToUnicodeConverter(rSet.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::createFromAscii(rtl_getMimeCharsetFromTextEncoding(rSet.m_nEncoding)) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ rtl_TextToUnicodeContext aContext
+ = rtl_createTextToUnicodeContext(aConverter);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeContext failed", aContext != nullptr);
+ sal_Size nSize;
+ sal_uInt32 nInfo;
+ sal_Size nConverted;
+ nSize = rtl_convertTextToUnicode(
+ aConverter, aContext, aText, 1, aUnicode, 1,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR),
+ &nInfo, &nConverted);
+
+ sal_uInt32 nExpectedInfo = (RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_UNDEFINED);
+
+ CPPUNIT_ASSERT_EQUAL(sal_Size(0), nSize);
+ CPPUNIT_ASSERT_EQUAL(nExpectedInfo, nInfo);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), nConverted);
+
+ rtl_destroyTextToUnicodeContext(aConverter, aContext);
+ rtl_destroyTextToUnicodeConverter(aConverter);
+ }
+ }
+}
+
+int const TEST_STRING_SIZE = 1000;
+
+struct ComplexCharSetTest {
+ rtl_TextEncoding m_nEncoding;
+ char const * m_pText;
+ sal_Size m_nTextSize;
+ sal_Unicode m_aUnicode[TEST_STRING_SIZE];
+ sal_Size m_nUnicodeSize;
+ bool m_bNoContext;
+ bool m_bForward;
+ bool m_bReverse;
+ bool m_bGlobalSignature;
+ sal_uInt32 m_nReverseUndefined;
+};
+
+void doComplexCharSetTest(ComplexCharSetTest const & rTest) {
+ if (rTest.m_bForward) {
+ sal_Unicode aUnicode[TEST_STRING_SIZE];
+ rtl_TextToUnicodeConverter aConverter
+ = rtl_createTextToUnicodeConverter(rTest.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::createFromAscii(rtl_getMimeCharsetFromTextEncoding(rTest.m_nEncoding)) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ rtl_TextToUnicodeContext aContext
+ = rtl_createTextToUnicodeContext(aConverter);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeContext failed", aContext != nullptr);
+ sal_Size nSize;
+ sal_uInt32 nInfo;
+ sal_Size nConverted;
+ nSize = rtl_convertTextToUnicode(
+ aConverter, aContext,
+ reinterpret_cast< char const * >(rTest.m_pText),
+ rTest.m_nTextSize, aUnicode, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH
+ | (rTest.m_bGlobalSignature ?
+ RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE : 0)),
+ &nInfo, &nConverted);
+ CPPUNIT_ASSERT_EQUAL(rTest.m_nUnicodeSize, nSize);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), nInfo);
+ CPPUNIT_ASSERT_EQUAL(rTest.m_nTextSize, nConverted);
+
+ rtl_destroyTextToUnicodeContext(aConverter, aContext);
+ rtl_destroyTextToUnicodeConverter(aConverter);
+
+ for (sal_Size i = 0; i < rTest.m_nUnicodeSize; ++i) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(aUnicode[i], 16) +
+ ", rTest.m_aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(rTest.m_aUnicode[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ rTest.m_aUnicode[i], aUnicode[i]);
+ }
+ }
+ if (rTest.m_bForward) {
+ sal_Unicode aUnicode[TEST_STRING_SIZE];
+ rtl_TextToUnicodeConverter aConverter
+ = rtl_createTextToUnicodeConverter(rTest.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::createFromAscii(rtl_getMimeCharsetFromTextEncoding(rTest.m_nEncoding)) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ rtl_TextToUnicodeContext aContext
+ = rtl_createTextToUnicodeContext(aConverter);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeContext failed", aContext != nullptr);
+ if (aContext != reinterpret_cast<rtl_TextToUnicodeContext>(1)) {
+ sal_Size nInput = 0;
+ sal_Size nOutput = 0;
+ for (bool bFlush = true; nInput < rTest.m_nTextSize || bFlush;) {
+ sal_Size nSrcBytes = 1;
+ sal_uInt32 nFlags
+ = (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR
+ | (rTest.m_bGlobalSignature ?
+ RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE : 0));
+ if (nInput >= rTest.m_nTextSize) {
+ nSrcBytes = 0;
+ nFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH;
+ bFlush = false;
+ }
+ sal_uInt32 nInfo;
+ sal_Size nConverted;
+ sal_Size nSize = rtl_convertTextToUnicode(
+ aConverter, aContext,
+ rTest.m_pText + nInput,
+ nSrcBytes, aUnicode + nOutput, TEST_STRING_SIZE - nOutput,
+ nFlags, &nInfo, &nConverted);
+ nOutput += nSize;
+ nInput += nConverted;
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0),
+ (nInfo & ~RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL));
+ }
+ CPPUNIT_ASSERT_EQUAL(rTest.m_nUnicodeSize, nOutput);
+ CPPUNIT_ASSERT_EQUAL(rTest.m_nTextSize, nInput);
+
+ for (sal_Size i = 0; i < rTest.m_nUnicodeSize; ++i) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(aUnicode[i], 16) +
+ ", rTest.m_aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(rTest.m_aUnicode[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ rTest.m_aUnicode[i], aUnicode[i]);
+ }
+ }
+ rtl_destroyTextToUnicodeContext(aConverter, aContext);
+ rtl_destroyTextToUnicodeConverter(aConverter);
+ }
+ if (rTest.m_bNoContext && rTest.m_bForward) {
+ sal_Unicode aUnicode[TEST_STRING_SIZE] = { 0, };
+ int nSize = 0;
+ rtl_TextToUnicodeConverter aConverter
+ = rtl_createTextToUnicodeConverter(rTest.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::createFromAscii(rtl_getMimeCharsetFromTextEncoding(rTest.m_nEncoding)) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ for (sal_Size i = 0;;) {
+ if (i == rTest.m_nTextSize) {
+ goto done;
+ }
+ char c1 = rTest.m_pText[i++];
+ sal_Unicode aUC[2];
+ sal_uInt32 nInfo = 0;
+ sal_Size nCvtBytes;
+ sal_Size nChars = rtl_convertTextToUnicode(
+ aConverter, nullptr, &c1, 1, aUC, 2,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR
+ | (rTest.m_bGlobalSignature ?
+ RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE : 0)),
+ &nInfo, &nCvtBytes);
+ if ((nInfo & RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0) {
+ char sBuffer[10];
+ sBuffer[0] = c1;
+ sal_uInt16 nLen = 1;
+ while ((nInfo & RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) != 0
+ && nLen < 10)
+ {
+ if (i == rTest.m_nTextSize) {
+ goto done;
+ }
+ c1 = rTest.m_pText[i++];
+ sBuffer[nLen++] = c1;
+ nChars = rtl_convertTextToUnicode(
+ aConverter, nullptr, sBuffer, nLen, aUC, 2,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR
+ | (rTest.m_bGlobalSignature ?
+ RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE : 0)),
+ &nInfo, &nCvtBytes);
+ }
+ if (nChars == 1 && nInfo == 0) {
+ OSL_ASSERT(nCvtBytes == nLen);
+ aUnicode[nSize++] = aUC[0];
+ } else if (nChars == 2 && nInfo == 0) {
+ OSL_ASSERT(nCvtBytes == nLen);
+ aUnicode[nSize++] = aUC[0];
+ aUnicode[nSize++] = aUC[1];
+ } else {
+ OSL_ASSERT(
+ (nInfo & RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL) == 0
+ && nChars == 0 && nInfo != 0);
+ aUnicode[nSize++] = sBuffer[0];
+ i -= nLen - 1;
+ }
+ } else if (nChars == 1 && nInfo == 0) {
+ OSL_ASSERT(nCvtBytes == 1);
+ aUnicode[nSize++] = aUC[0];
+ } else if (nChars == 2 && nInfo == 0) {
+ OSL_ASSERT(nCvtBytes == 1);
+ aUnicode[nSize++] = aUC[0];
+ aUnicode[nSize++] = aUC[1];
+ } else {
+ OSL_ASSERT(nChars == 0 && nInfo != 0);
+ aUnicode[nSize++] = c1;
+ }
+ }
+ done:
+ rtl_destroyTextToUnicodeConverter(aConverter);
+ for (sal_Size i = 0; i < rTest.m_nUnicodeSize; ++i) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(aUnicode[i], 16) +
+ ", rTest.m_aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(rTest.m_aUnicode[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ rTest.m_aUnicode[i], aUnicode[i]);
+ }
+ }
+ if (rTest.m_bReverse) {
+ char aText[TEST_STRING_SIZE];
+ rtl_UnicodeToTextConverter aConverter
+ = rtl_createUnicodeToTextConverter(rTest.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::createFromAscii(rtl_getMimeCharsetFromTextEncoding(rTest.m_nEncoding)) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ rtl_UnicodeToTextContext aContext
+ = rtl_createUnicodeToTextContext(aConverter);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeContext failed", aContext != nullptr);
+ sal_Size nSize;
+ sal_uInt32 nInfo;
+ sal_Size nConverted;
+ nSize = rtl_convertUnicodeToText(
+ aConverter, aContext, rTest.m_aUnicode, rTest.m_nUnicodeSize, aText,
+ TEST_STRING_SIZE,
+ (rTest.m_nReverseUndefined | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_FLUSH
+ | (rTest.m_bGlobalSignature ?
+ RTL_UNICODETOTEXT_FLAGS_GLOBAL_SIGNATURE : 0)),
+ &nInfo, &nConverted);
+ CPPUNIT_ASSERT_EQUAL(rTest.m_nTextSize, nSize);
+ if (nInfo != 0)
+ {
+ CPPUNIT_ASSERT_EQUAL(RTL_UNICODETOTEXT_INFO_UNDEFINED, nInfo);
+ CPPUNIT_ASSERT_MESSAGE("rTest.m_nReverseUndefined should not be RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR",
+ rTest.m_nReverseUndefined != RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR);
+ }
+ CPPUNIT_ASSERT_EQUAL(rTest.m_nUnicodeSize, nConverted);
+ rtl_destroyUnicodeToTextContext(aConverter, aContext);
+ rtl_destroyUnicodeToTextConverter(aConverter);
+ for (sal_Size i = 0; i < rTest.m_nTextSize; ++i) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("aText[" + OUString::number(i) + "] == " +
+ OUString::number(aText[i], 16) +
+ ", rTest.m_pText[" + OUString::number(i) + "] == " +
+ OUString::number(rTest.m_pText[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ rTest.m_pText[i], aText[i]);
+ }
+ }
+}
+
+void doComplexCharSetCutTest(ComplexCharSetTest const & rTest) {
+ if (rTest.m_bNoContext) {
+ sal_Unicode aUnicode[TEST_STRING_SIZE];
+ rtl_TextToUnicodeConverter aConverter
+ = rtl_createTextToUnicodeConverter(rTest.m_nEncoding);
+ CPPUNIT_ASSERT_MESSAGE(OUStringToOString(OUStringConcatenation("rtl_createTextToUnicodeConverter(" + OUString::createFromAscii(rtl_getMimeCharsetFromTextEncoding(rTest.m_nEncoding)) + ") failed"),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ aConverter != nullptr);
+ sal_Size nSize;
+ sal_uInt32 nInfo;
+ sal_Size nConverted;
+ nSize = rtl_convertTextToUnicode(
+ aConverter, nullptr, reinterpret_cast< char const * >(rTest.m_pText),
+ rTest.m_nTextSize, aUnicode, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR),
+ &nInfo, &nConverted);
+
+ CPPUNIT_ASSERT_EQUAL(rTest.m_nUnicodeSize, nSize);
+ if (nInfo != RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL)
+ {
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL,
+ nInfo);
+ }
+ CPPUNIT_ASSERT_MESSAGE("nConverted should be less than rTest.m_nTextSize", nConverted < rTest.m_nTextSize);
+
+ rtl_destroyTextToUnicodeConverter(aConverter);
+ for (sal_Size i = 0; i < nSize; ++i) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(OUStringConcatenation("aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(aUnicode[i], 16) +
+ ", rTest.m_aUnicode[" + OUString::number(i) + "] == " +
+ OUString::number(rTest.m_aUnicode[i], 16)),
+ RTL_TEXTENCODING_UTF8).getStr(),
+ rTest.m_aUnicode[i], aUnicode[i]);
+ }
+ }
+}
+
+class Test: public CppUnit::TestFixture {
+public:
+ void testSingleByte();
+
+ void testComplex();
+
+ void testComplexCut();
+
+ void testInvalidUtf7();
+
+ void testInvalidUtf8();
+
+ void testInvalidUnicode();
+
+ void testSRCBUFFERTOSMALL();
+
+ void testMime();
+
+ void testWindows();
+
+ void testInfo();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testSingleByte);
+ CPPUNIT_TEST(testComplex);
+ CPPUNIT_TEST(testComplexCut);
+ CPPUNIT_TEST(testInvalidUtf7);
+ CPPUNIT_TEST(testInvalidUtf8);
+ CPPUNIT_TEST(testInvalidUnicode);
+ CPPUNIT_TEST(testSRCBUFFERTOSMALL);
+ CPPUNIT_TEST(testMime);
+ CPPUNIT_TEST(testWindows);
+ CPPUNIT_TEST(testInfo);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::testSingleByte() {
+ static SingleByteCharSet const data[]
+ = { { RTL_TEXTENCODING_MS_1250,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0xFFFF,0x201E,0x2026,0x2020,0x2021,
+ 0xFFFF,0x2030,0x0160,0x2039,0x015A,0x0164,0x017D,0x0179,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0xFFFF,0x2122,0x0161,0x203A,0x015B,0x0165,0x017E,0x017A,
+ 0x00A0,0x02C7,0x02D8,0x0141,0x00A4,0x0104,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x015E,0x00AB,0x00AC,0x00AD,0x00AE,0x017B,
+ 0x00B0,0x00B1,0x02DB,0x0142,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x0105,0x015F,0x00BB,0x013D,0x02DD,0x013E,0x017C,
+ 0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,
+ 0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,
+ 0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,
+ 0x0158,0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,
+ 0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,
+ 0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,
+ 0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7,
+ 0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9 } },
+ { RTL_TEXTENCODING_MS_1251,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021,
+ 0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F,
+ 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0xFFFF,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F,
+ 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7,
+ 0x0401,0x00A9,0x0404,0x00AB,0x00AC,0x00AD,0x00AE,0x0407,
+ 0x00B0,0x00B1,0x0406,0x0456,0x0491,0x00B5,0x00B6,0x00B7,
+ 0x0451,0x2116,0x0454,0x00BB,0x0458,0x0405,0x0455,0x0457,
+ 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,
+ 0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,
+ 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,
+ 0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,
+ 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,
+ 0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,
+ 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,
+ 0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F } },
+ { RTL_TEXTENCODING_MS_1252,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
+ 0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFF,0x017D,0xFFFF,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0x02DC,0x2122,0x0161,0x203A,0x0153,0xFFFF,0x017E,0x0178,
+ 0x00A0,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
+ 0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7,
+ 0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
+ 0x00D0,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D7,
+ 0x00D8,0x00D9,0x00DA,0x00DB,0x00DC,0x00DD,0x00DE,0x00DF,
+ 0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7,
+ 0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
+ 0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7,
+ 0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x00FD,0x00FE,0x00FF } },
+ { RTL_TEXTENCODING_MS_1253,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
+ 0xFFFF,0x2030,0xFFFF,0x2039,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0xFFFF,0x2122,0xFFFF,0x203A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x00A0,0x0385,0x0386,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0xFFFF,0x00AB,0x00AC,0x00AD,0x00AE,0x2015,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x0384,0x00B5,0x00B6,0x00B7,
+ 0x0388,0x0389,0x038A,0x00BB,0x038C,0x00BD,0x038E,0x038F,
+ 0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,
+ 0x0398,0x0399,0x039A,0x039B,0x039C,0x039D,0x039E,0x039F,
+ 0x03A0,0x03A1,0xFFFF,0x03A3,0x03A4,0x03A5,0x03A6,0x03A7,
+ 0x03A8,0x03A9,0x03AA,0x03AB,0x03AC,0x03AD,0x03AE,0x03AF,
+ 0x03B0,0x03B1,0x03B2,0x03B3,0x03B4,0x03B5,0x03B6,0x03B7,
+ 0x03B8,0x03B9,0x03BA,0x03BB,0x03BC,0x03BD,0x03BE,0x03BF,
+ 0x03C0,0x03C1,0x03C2,0x03C3,0x03C4,0x03C5,0x03C6,0x03C7,
+ 0x03C8,0x03C9,0x03CA,0x03CB,0x03CC,0x03CD,0x03CE,0xFFFF } },
+ { RTL_TEXTENCODING_MS_1254,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
+ 0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0x02DC,0x2122,0x0161,0x203A,0x0153,0xFFFF,0xFFFF,0x0178,
+ 0x00A0,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
+ 0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7,
+ 0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
+ 0x011E,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D7,
+ 0x00D8,0x00D9,0x00DA,0x00DB,0x00DC,0x0130,0x015E,0x00DF,
+ 0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7,
+ 0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
+ 0x011F,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7,
+ 0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x0131,0x015F,0x00FF } },
+ { RTL_TEXTENCODING_APPLE_ROMAN,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E, 0x7F,
+ 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
+ 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
+ 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
+ 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
+ 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
+ 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
+ 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
+ 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
+ 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
+ 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
+ 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
+ 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
+ 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
+ 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
+ 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
+ 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7 } },
+ { RTL_TEXTENCODING_IBM_437,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,
+ 0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5,
+ 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,
+ 0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192,
+ 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,
+ 0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb,
+ 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,
+ 0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510,
+ 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,
+ 0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567,
+ 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,
+ 0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580,
+ 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,
+ 0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229,
+ 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,
+ 0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 } },
+
+ { RTL_TEXTENCODING_ASCII_US,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021, // !
+ 0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFF,0x017D,0xFFFF, // !
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, // !
+ 0x02DC,0x2122,0x0161,0x203A,0x0153,0xFFFF,0x017E,0x0178, // !
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+ 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+ 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+ 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF } },
+ { RTL_TEXTENCODING_ISO_8859_1,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
+ 0x00A0,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
+ 0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7,
+ 0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
+ 0x00D0,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D7,
+ 0x00D8,0x00D9,0x00DA,0x00DB,0x00DC,0x00DD,0x00DE,0x00DF,
+ 0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7,
+ 0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
+ 0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7,
+ 0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x00FD,0x00FE,0x00FF } },
+ { RTL_TEXTENCODING_ISO_8859_2,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
+ 0x00A0,0x0104,0x02D8,0x0141,0x00A4,0x013D,0x015A,0x00A7,
+ 0x00A8,0x0160,0x015E,0x0164,0x0179,0x00AD,0x017D,0x017B,
+ 0x00B0,0x0105,0x02DB,0x0142,0x00B4,0x013E,0x015B,0x02C7,
+ 0x00B8,0x0161,0x015F,0x0165,0x017A,0x02DD,0x017E,0x017C,
+ 0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,
+ 0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,
+ 0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,
+ 0x0158,0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,
+ 0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,
+ 0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,
+ 0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7,
+ 0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9 } },
+ { RTL_TEXTENCODING_ISO_8859_3,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
+ 0x00A0,0x0126,0x02D8,0x00A3,0x00A4,0xFFFF,0x0124,0x00A7,
+ 0x00A8,0x0130,0x015E,0x011E,0x0134,0x00AD,0xFFFF,0x017B,
+ 0x00B0,0x0127,0x00B2,0x00B3,0x00B4,0x00B5,0x0125,0x00B7,
+ 0x00B8,0x0131,0x015F,0x011F,0x0135,0x00BD,0xFFFF,0x017C,
+ 0x00C0,0x00C1,0x00C2,0xFFFF,0x00C4,0x010A,0x0108,0x00C7,
+ 0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
+ 0xFFFF,0x00D1,0x00D2,0x00D3,0x00D4,0x0120,0x00D6,0x00D7,
+ 0x011C,0x00D9,0x00DA,0x00DB,0x00DC,0x016C,0x015C,0x00DF,
+ 0x00E0,0x00E1,0x00E2,0xFFFF,0x00E4,0x010B,0x0109,0x00E7,
+ 0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
+ 0xFFFF,0x00F1,0x00F2,0x00F3,0x00F4,0x0121,0x00F6,0x00F7,
+ 0x011D,0x00F9,0x00FA,0x00FB,0x00FC,0x016D,0x015D,0x02D9 } },
+
+ { RTL_TEXTENCODING_ISO_8859_6,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
+ 0x00A0,0xFFFF,0xFFFF,0xFFFF,0x00A4,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x060C,0x00AD,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0x061B,0xFFFF,0xFFFF,0xFFFF,0x061F,
+ 0xFFFF,0x0621,0x0622,0x0623,0x0624,0x0625,0x0626,0x0627,
+ 0x0628,0x0629,0x062A,0x062B,0x062C,0x062D,0x062E,0x062F,
+ 0x0630,0x0631,0x0632,0x0633,0x0634,0x0635,0x0636,0x0637,
+ 0x0638,0x0639,0x063A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x0640,0x0641,0x0642,0x0643,0x0644,0x0645,0x0646,0x0647,
+ 0x0648,0x0649,0x064A,0x064B,0x064C,0x064D,0x064E,0x064F,
+ 0x0650,0x0651,0x0652,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF } },
+
+ { RTL_TEXTENCODING_ISO_8859_8,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
+ 0x00A0,0xFFFF,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x00D7,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x00B9,0x00F7,0x00BB,0x00BC,0x00BD,0x00BE,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x2017,
+ 0x05D0,0x05D1,0x05D2,0x05D3,0x05D4,0x05D5,0x05D6,0x05D7,
+ 0x05D8,0x05D9,0x05DA,0x05DB,0x05DC,0x05DD,0x05DE,0x05DF,
+ 0x05E0,0x05E1,0x05E2,0x05E3,0x05E4,0x05E5,0x05E6,0x05E7,
+ 0x05E8,0x05E9,0x05EA,0xFFFF,0xFFFF,0x200E,0x200F,0xFFFF } },
+
+ { RTL_TEXTENCODING_TIS_620,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
+ 0x00A0,0x0E01,0x0E02,0x0E03,0x0E04,0x0E05,0x0E06,0x0E07, // !
+ 0x0E08,0x0E09,0x0E0A,0x0E0B,0x0E0C,0x0E0D,0x0E0E,0x0E0F,
+ 0x0E10,0x0E11,0x0E12,0x0E13,0x0E14,0x0E15,0x0E16,0x0E17,
+ 0x0E18,0x0E19,0x0E1A,0x0E1B,0x0E1C,0x0E1D,0x0E1E,0x0E1F,
+ 0x0E20,0x0E21,0x0E22,0x0E23,0x0E24,0x0E25,0x0E26,0x0E27,
+ 0x0E28,0x0E29,0x0E2A,0x0E2B,0x0E2C,0x0E2D,0x0E2E,0x0E2F,
+ 0x0E30,0x0E31,0x0E32,0x0E33,0x0E34,0x0E35,0x0E36,0x0E37,
+ 0x0E38,0x0E39,0x0E3A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x0E3F,
+ 0x0E40,0x0E41,0x0E42,0x0E43,0x0E44,0x0E45,0x0E46,0x0E47,
+ 0x0E48,0x0E49,0x0E4A,0x0E4B,0x0E4C,0x0E4D,0x0E4E,0x0E4F,
+ 0x0E50,0x0E51,0x0E52,0x0E53,0x0E54,0x0E55,0x0E56,0x0E57,
+ 0x0E58,0x0E59,0x0E5A,0x0E5B,0xFFFF,0xFFFF,0xFFFF,0xFFFF } },
+ { RTL_TEXTENCODING_MS_874,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x2026,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x00A0,0x0E01,0x0E02,0x0E03,0x0E04,0x0E05,0x0E06,0x0E07,
+ 0x0E08,0x0E09,0x0E0A,0x0E0B,0x0E0C,0x0E0D,0x0E0E,0x0E0F,
+ 0x0E10,0x0E11,0x0E12,0x0E13,0x0E14,0x0E15,0x0E16,0x0E17,
+ 0x0E18,0x0E19,0x0E1A,0x0E1B,0x0E1C,0x0E1D,0x0E1E,0x0E1F,
+ 0x0E20,0x0E21,0x0E22,0x0E23,0x0E24,0x0E25,0x0E26,0x0E27,
+ 0x0E28,0x0E29,0x0E2A,0x0E2B,0x0E2C,0x0E2D,0x0E2E,0x0E2F,
+ 0x0E30,0x0E31,0x0E32,0x0E33,0x0E34,0x0E35,0x0E36,0x0E37,
+ 0x0E38,0x0E39,0x0E3A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x0E3F,
+ 0x0E40,0x0E41,0x0E42,0x0E43,0x0E44,0x0E45,0x0E46,0x0E47,
+ 0x0E48,0x0E49,0x0E4A,0x0E4B,0x0E4C,0x0E4D,0x0E4E,0x0E4F,
+ 0x0E50,0x0E51,0x0E52,0x0E53,0x0E54,0x0E55,0x0E56,0x0E57,
+ 0x0E58,0x0E59,0x0E5A,0x0E5B,0xFFFF,0xFFFF,0xFFFF,0xFFFF } },
+ { RTL_TEXTENCODING_MS_1255,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
+ 0x02C6,0x2030,0xFFFF,0x2039,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0x02DC,0x2122,0xFFFF,0x203A,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x00A0,0x00A1,0x00A2,0x00A3,0x20AA,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x00D7,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x00B9,0x00F7,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
+ 0x05B0,0x05B1,0x05B2,0x05B3,0x05B4,0x05B5,0x05B6,0x05B7,
+ 0x05B8,0x05B9,0xFFFF,0x05BB,0x05BC,0x05BD,0x05BE,0x05BF,
+ 0x05C0,0x05C1,0x05C2,0x05C3,0x05F0,0x05F1,0x05F2,0x05F3,
+ 0x05F4,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x05D0,0x05D1,0x05D2,0x05D3,0x05D4,0x05D5,0x05D6,0x05D7,
+ 0x05D8,0x05D9,0x05DA,0x05DB,0x05DC,0x05DD,0x05DE,0x05DF,
+ 0x05E0,0x05E1,0x05E2,0x05E3,0x05E4,0x05E5,0x05E6,0x05E7,
+ 0x05E8,0x05E9,0x05EA,0xFFFF,0xFFFF,0x200E,0x200F,0xFFFF } },
+ { RTL_TEXTENCODING_MS_1256,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0x067E,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
+ 0x02C6,0x2030,0x0679,0x2039,0x0152,0x0686,0x0698,0x0688,
+ 0x06AF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0x06A9,0x2122,0x0691,0x203A,0x0153,0x200C,0x200D,0x06BA,
+ 0x00A0,0x060C,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x06BE,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x00B9,0x061B,0x00BB,0x00BC,0x00BD,0x00BE,0x061F,
+ 0x06C1,0x0621,0x0622,0x0623,0x0624,0x0625,0x0626,0x0627,
+ 0x0628,0x0629,0x062A,0x062B,0x062C,0x062D,0x062E,0x062F,
+ 0x0630,0x0631,0x0632,0x0633,0x0634,0x0635,0x0636,0x00D7,
+ 0x0637,0x0638,0x0639,0x063A,0x0640,0x0641,0x0642,0x0643,
+ 0x00E0,0x0644,0x00E2,0x0645,0x0646,0x0647,0x0648,0x00E7,
+ 0x00E8,0x00E9,0x00EA,0x00EB,0x0649,0x064A,0x00EE,0x00EF,
+ 0x064B,0x064C,0x064D,0x064E,0x00F4,0x064F,0x0650,0x00F7,
+ 0x0651,0x00F9,0x0652,0x00FB,0x00FC,0x200E,0x200F,0x06D2 } },
+ { RTL_TEXTENCODING_MS_1257,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0xFFFF,0x201E,0x2026,0x2020,0x2021,
+ 0xFFFF,0x2030,0xFFFF,0x2039,0xFFFF,0x00A8,0x02C7,0x00B8,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0xFFFF,0x2122,0xFFFF,0x203A,0xFFFF,0x00AF,0x02DB,0xFFFF,
+ 0x00A0,0xFFFF,0x00A2,0x00A3,0x00A4,0xFFFF,0x00A6,0x00A7,
+ 0x00D8,0x00A9,0x0156,0x00AB,0x00AC,0x00AD,0x00AE,0x00C6,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00F8,0x00B9,0x0157,0x00BB,0x00BC,0x00BD,0x00BE,0x00E6,
+ 0x0104,0x012E,0x0100,0x0106,0x00C4,0x00C5,0x0118,0x0112,
+ 0x010C,0x00C9,0x0179,0x0116,0x0122,0x0136,0x012A,0x013B,
+ 0x0160,0x0143,0x0145,0x00D3,0x014C,0x00D5,0x00D6,0x00D7,
+ 0x0172,0x0141,0x015A,0x016A,0x00DC,0x017B,0x017D,0x00DF,
+ 0x0105,0x012F,0x0101,0x0107,0x00E4,0x00E5,0x0119,0x0113,
+ 0x010D,0x00E9,0x017A,0x0117,0x0123,0x0137,0x012B,0x013C,
+ 0x0161,0x0144,0x0146,0x00F3,0x014D,0x00F5,0x00F6,0x00F7,
+ 0x0173,0x0142,0x015B,0x016B,0x00FC,0x017C,0x017E,0x02D9 } },
+ { RTL_TEXTENCODING_MS_1258,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x20AC,0xFFFF,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
+ 0x02C6,0x2030,0xFFFF,0x2039,0x0152,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0x02DC,0x2122,0xFFFF,0x203A,0x0153,0xFFFF,0xFFFF,0x0178,
+ 0x00A0,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
+ 0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
+ 0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
+ 0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
+ 0x00C0,0x00C1,0x00C2,0x0102,0x00C4,0x00C5,0x00C6,0x00C7,
+ 0x00C8,0x00C9,0x00CA,0x00CB,0x0300,0x00CD,0x00CE,0x00CF,
+ 0x0110,0x00D1,0x0309,0x00D3,0x00D4,0x01A0,0x00D6,0x00D7,
+ 0x00D8,0x00D9,0x00DA,0x00DB,0x00DC,0x01AF,0x0303,0x00DF,
+ 0x00E0,0x00E1,0x00E2,0x0103,0x00E4,0x00E5,0x00E6,0x00E7,
+ 0x00E8,0x00E9,0x00EA,0x00EB,0x0301,0x00ED,0x00EE,0x00EF,
+ 0x0111,0x00F1,0x0323,0x00F3,0x00F4,0x01A1,0x00F6,0x00F7,
+ 0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x01B0,0x20AB,0x00FF } },
+ { RTL_TEXTENCODING_KOI8_U, // RFC 2319
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x2500,0x2502,0x250C,0x2510,0x2514,0x2518,0x251C,0x2524,
+ 0x252C,0x2534,0x253C,0x2580,0x2584,0x2588,0x258C,0x2590,
+ 0x2591,0x2592,0x2593,0x2320,0x25A0,0x2219,0x221A,0x2248,
+ 0x2264,0x2265,0x00A0,0x2321,0x00B0,0x00B2,0x00B7,0x00F7,
+ 0x2550,0x2551,0x2552,0x0451,0x0454,0x2554,0x0456,0x0457,
+ 0x2557,0x2558,0x2559,0x255A,0x255B,0x0491,0x255D,0x255E,
+ 0x255F,0x2560,0x2561,0x0401,0x0404,0x2563,0x0406,0x0407,
+ 0x2566,0x2567,0x2568,0x2569,0x256A,0x0490,0x256C,0x00A9,
+ 0x044E,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433,
+ 0x0445,0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,
+ 0x043F,0x044F,0x0440,0x0441,0x0442,0x0443,0x0436,0x0432,
+ 0x044C,0x044B,0x0437,0x0448,0x044D,0x0449,0x0447,0x044A,
+ 0x042E,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413,
+ 0x0425,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,
+ 0x041F,0x042F,0x0420,0x0421,0x0422,0x0423,0x0416,0x0412,
+ 0x042C,0x042B,0x0417,0x0428,0x042D,0x0429,0x0427,0x042A } },
+ { RTL_TEXTENCODING_ADOBE_STANDARD,
+ { 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x2019,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x2018,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x00A1,0x00A2,0x00A3,0x2215,0x00A5,0x0192,0x00A7,
+ 0x00A4,0x0027,0x201C,0x00AB,0x2039,0x203A,0xFB01,0xFB02,
+ 0xFFFF,0x2013,0x2020,0x2021,0x00B7,0xFFFF,0x00B6,0x2022,
+ 0x201A,0x201E,0x201D,0x00BB,0x2026,0x2030,0xFFFF,0x00BF,
+ 0xFFFF,0x0060,0x00B4,0x02C6,0x02DC,0x00AF,0x02D8,0x02D9,
+ 0x00A8,0xFFFF,0x02DA,0x00B8,0xFFFF,0x02DD,0x02DB,0x02C7,
+ 0x2014,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x00C6,0xFFFF,0x00AA,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x0141,0x00D8,0x0152,0x00BA,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0x00E6,0xFFFF,0xFFFF,0xFFFF,0x0131,0xFFFF,0xFFFF,
+ 0x0142,0x00F8,0x0153,0x00DF,0xFFFF,0xFFFF,0xFFFF,0xFFFF } },
+ { RTL_TEXTENCODING_ADOBE_SYMBOL,
+ { 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x0020,0x0021,0x2200,0x0023,0x2203,0x0025,0x0026,0x220B,
+ 0x0028,0x0029,0x2217,0x002B,0x002C,0x2212,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x2245,0x0391,0x0392,0x03A7,0x0394,0x0395,0x03A6,0x0393,
+ 0x0397,0x0399,0x03D1,0x039A,0x039B,0x039C,0x039D,0x039F,
+ 0x03A0,0x0398,0x03A1,0x03A3,0x03A4,0x03A5,0x03C2,0x03A9,
+ 0x039E,0x03A8,0x0396,0x005B,0x2234,0x005D,0x22A5,0x005F,
+ 0xF8E5,0x03B1,0x03B2,0x03C7,0x03B4,0x03B5,0x03C6,0x03B3,
+ 0x03B7,0x03B9,0x03D5,0x03BA,0x03BB,0x03BC,0x03BD,0x03BF,
+ 0x03C0,0x03B8,0x03C1,0x03C3,0x03C4,0x03C5,0x03D6,0x03C9,
+ 0x03BE,0x03C8,0x03B6,0x007B,0x007C,0x007D,0x223C,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0x20AC,0x03D2,0x2032,0x2264,0x2215,0x221E,0x0192,0x2663,
+ 0x2666,0x2665,0x2660,0x2194,0x2190,0x2191,0x2192,0x2193,
+ 0x00B0,0x00B1,0x2033,0x2265,0x00D7,0x221D,0x2202,0x2022,
+ 0x00F7,0x2260,0x2261,0x2248,0x2026,0x23AF,0x23D0,0x21B5,
+ 0x2135,0x2111,0x211C,0x2118,0x2297,0x2295,0x2205,0x2229,
+ 0x222A,0x2283,0x2287,0x2284,0x2282,0x2286,0x2208,0x2209,
+ 0x2220,0x2207,0xF6DA,0xF6D9,0xF6DB,0x220F,0x221A,0x22C5,
+ 0x00AC,0x2227,0x2228,0x21D4,0x21D0,0x21D1,0x21D2,0x21D3,
+ 0x25CA,0x2329,0xF8E8,0xF8E9,0xF8EA,0x2211,0x239B,0x239C,
+ 0x239D,0x23A1,0x23A2,0x23A3,0x23A7,0x23A8,0x23A9,0x23AA,
+ 0xFFFF,0x232A,0x222B,0x2320,0x23AE,0x2321,0x239E,0x239F,
+ 0x23A0,0x23A4,0x23A5,0x23A6,0x23AB,0x23AC,0x23AD,0xFFFF } },
+ { RTL_TEXTENCODING_ADOBE_DINGBATS,
+ { 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+// 20
+ 0x0020,0x2701,0x2702,0x2703,0x2704,0x260E,0x2706,0x2707,
+ 0x2708,0x2709,0x261B,0x261E,0x270C,0x270D,0x270E,0x270F,
+ 0x2710,0x2711,0x2712,0x2713,0x2714,0x2715,0x2716,0x2717,
+ 0x2718,0x2719,0x271A,0x271B,0x271C,0x271D,0x271E,0x271F,
+// 40
+ 0x2720,0x2721,0x2722,0x2723,0x2724,0x2725,0x2726,0x2727,
+ 0x2605,0x2729,0x272A,0x272B,0x272C,0x272D,0x272E,0x272F,
+ 0x2730,0x2731,0x2732,0x2733,0x2734,0x2735,0x2736,0x2737,
+ 0x2738,0x2739,0x273A,0x273B,0x273C,0x273D,0x273E,0x273F,
+// 60
+ 0x2740,0x2741,0x2742,0x2743,0x2744,0x2745,0x2746,0x2747,
+ 0x2748,0x2749,0x274A,0x274B,0x25CF,0x274D,0x25A0,0x274F,
+ 0x2750,0x2751,0x2752,0x25B2,0x25BC,0x25C6,0x2756,0x25D7,
+ 0x2758,0x2759,0x275A,0x275B,0x275C,0x275D,0x275E,0xFFFF,
+// 80
+ 0xF8D7,0xF8D8,0xF8D9,0xF8DA,0xF8DB,0xF8DC,0xF8DD,0xF8DE,
+ 0xF8DF,0xF8E0,0xF8E1,0xF8E2,0xF8E3,0xF8E4,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
+// A0
+ 0xFFFF,0x2761,0x2762,0x2763,0x2764,0x2765,0x2766,0x2767,
+ 0x2663,0x2666,0x2665,0x2660,0x2460,0x2461,0x2462,0x2463,
+ 0x2464,0x2465,0x2466,0x2467,0x2468,0x2469,0x2776,0x2777,
+ 0x2778,0x2779,0x277A,0x277B,0x277C,0x277D,0x277E,0x277F,
+// C0
+ 0x2780,0x2781,0x2782,0x2783,0x2784,0x2785,0x2786,0x2787,
+ 0x2788,0x2789,0x278A,0x278B,0x278C,0x278D,0x278E,0x278F,
+ 0x2790,0x2791,0x2792,0x2793,0x2794,0x2795,0x2796,0x2797,
+ 0x2798,0x2799,0x279A,0x279B,0x279C,0x279D,0x279E,0x279F,
+// E0
+ 0x27A0,0x27A1,0x27A2,0x27A3,0x27A4,0x27A5,0x27A6,0x27A7,
+ 0x27A8,0x27A9,0x27AA,0x27AB,0x27AC,0x27AD,0x27AE,0x27AF,
+ 0xFFFF,0x27B1,0x27B2,0x27B3,0x27B4,0x27B5,0x27B6,0x27B7,
+ 0x27B8,0x27B9,0x27BA,0x27BB,0x27BC,0x27BD,0x27BE,0xFFFF } },
+ { RTL_TEXTENCODING_PT154,
+ { 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F,
+ 0x0496,0x0492,0x04EE,0x0493,0x201E,0x2026,0x04B6,0x04AE,
+ 0x04B2,0x04AF,0x04A0,0x04E2,0x04A2,0x049A,0x04BA,0x04B8,
+ 0x0497,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
+ 0x04B3,0x04B7,0x04A1,0x04E3,0x04A3,0x049B,0x04BB,0x04B9,
+ 0x00A0,0x040E,0x045E,0x0408,0x04E8,0x0498,0x04B0,0x00A7,
+ 0x0401,0x00A9,0x04D8,0x00AB,0x00AC,0x04EF,0x00AE,0x049C,
+ 0x00B0,0x04B1,0x0406,0x0456,0x0499,0x04E9,0x00B6,0x00B7,
+ 0x0451,0x2116,0x04D9,0x00BB,0x0458,0x04AA,0x04AB,0x049D,
+ 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,
+ 0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,
+ 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,
+ 0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,
+ 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,
+ 0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,
+ 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,
+ 0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F } } };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ testSingleByteCharSet(data[i]);
+ }
+}
+
+void Test::testComplex() {
+ static ComplexCharSetTest const data[]
+ = { { RTL_TEXTENCODING_ASCII_US,
+ RTL_CONSTASCII_STRINGPARAM("\x01\"3De$~"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x007E },
+ 7,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ { RTL_TEXTENCODING_EUC_CN,
+ RTL_CONSTASCII_STRINGPARAM("\x01\"3De$~\xA1\xB9\xF0\xC5"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x007E,
+ 0x300D,0x9E4B },
+ 9,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_TW,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x01\"3De$~\xC5\xF0\x8E\xA4\xDC\xD9"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x007E,
+ 0x4ED9,0xD87E,0xDD68 },
+ 10,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_GB_18030,
+ RTL_CONSTASCII_STRINGPARAM("\x01\"3De$~"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x007E },
+ 7,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_GB_18030,
+ RTL_CONSTASCII_STRINGPARAM("\x81\x40\xFE\xFE"),
+ { 0x4E02,0xE4C5 },
+ 2,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_GB_18030,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x81\x30\xB1\x33\x81\x30\xD3\x30\x81\x36\xA5\x31"),
+ { 0x028A,0x0452,0x200F },
+ 3,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_GB_18030,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xFE\x50\xFE\x51\xFE\x52\xFE\x53\xFE\x54\xFE\x55\xFE\x56"
+ "\xFE\x57\xFE\x58\xFE\x59\xFE\x5A\xFE\x5B\xFE\x5C\xFE\x5D"
+ "\xFE\x5E\xFE\x5F\xFE\x60\xFE\x61\xFE\x62\xFE\x63\xFE\x64"
+ "\xFE\x65\xFE\x66\xFE\x67\xFE\x68\xFE\x69\xFE\x6A\xFE\x6B"
+ "\xFE\x6C\xFE\x6D\xFE\x6E\xFE\x6F\xFE\x70\xFE\x71\xFE\x72"
+ "\xFE\x73\xFE\x74\xFE\x75\xFE\x76\xFE\x77\xFE\x78\xFE\x79"
+ "\xFE\x7A\xFE\x7B\xFE\x7C\xFE\x7D\xFE\x7E\xFE\x80\xFE\x81"
+ "\xFE\x82\xFE\x83\xFE\x84\xFE\x85\xFE\x86\xFE\x87\xFE\x88"
+ "\xFE\x89\xFE\x8A\xFE\x8B\xFE\x8C\xFE\x8D\xFE\x8E\xFE\x8F"
+ "\xFE\x90\xFE\x91\xFE\x92\xFE\x93\xFE\x94\xFE\x95\xFE\x96"
+ "\xFE\x97\xFE\x98\xFE\x99\xFE\x9A\xFE\x9B\xFE\x9C\xFE\x9D"
+ "\xFE\x9E\xFE\x9F\xFE\xA0"),
+ { 0x2E81,0xE816,0xE817,0xE818,0x2E84,0x3473,0x3447,0x2E88,
+ 0x2E8B,0xE81E,0x359E,0x361A,0x360E,0x2E8C,0x2E97,0x396E,
+ 0x3918,0xE826,0x39CF,0x39DF,0x3A73,0x39D0,0xE82B,0xE82C,
+ 0x3B4E,0x3C6E,0x3CE0,0x2EA7,0xE831,0xE832,0x2EAA,0x4056,
+ 0x415F,0x2EAE,0x4337,0x2EB3,0x2EB6,0x2EB7,0xE83B,0x43B1,
+ 0x43AC,0x2EBB,0x43DD,0x44D6,0x4661,0x464C,0xE843,0x4723,
+ 0x4729,0x477C,0x478D,0x2ECA,0x4947,0x497A,0x497D,0x4982,
+ 0x4983,0x4985,0x4986,0x499F,0x499B,0x49B7,0x49B6,0xE854,
+ 0xE855,0x4CA3,0x4C9F,0x4CA0,0x4CA1,0x4C77,0x4CA2,0x4D13,
+ 0x4D14,0x4D15,0x4D16,0x4D17,0x4D18,0x4D19,0x4DAE,0xE864 },
+ 80,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ { RTL_TEXTENCODING_ISO_2022_JP,
+ RTL_CONSTASCII_STRINGPARAM("\x01\"3De$\\~"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x005C,0x007E },
+ 8,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_2022_JP,
+ RTL_CONSTASCII_STRINGPARAM("\x1B(B\x01\"3De$\\~"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x005C,0x007E },
+ 8,
+ false,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_2022_JP,
+ RTL_CONSTASCII_STRINGPARAM("\x1B(J\x01\"3De$\\~"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x00A5,0x00AF },
+ 8,
+ false,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_2022_JP,
+ RTL_CONSTASCII_STRINGPARAM("\x1B$B\x26\x21\x27\x71\x1B(B"),
+ { 0x0391,0x044F },
+ 2,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ { RTL_TEXTENCODING_ISO_2022_KR,
+ RTL_CONSTASCII_STRINGPARAM("\x1B$)C\x01\"3De$\\~"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x005C,0x007E },
+ 8,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_2022_KR,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x1B$)C\x0E\x25\x21\x0F\x0D\x0Ax\x0E\x48\x7E\x0F"),
+ { 0x2170,0x000D,0x000A,0x0078,0xD79D },
+ 5,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ { RTL_TEXTENCODING_ISO_2022_CN,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x01\"3De$\\~\x1B$)G\x0E\x45\x70\x1B$*H\x1BN\x22\x22"
+ "\x45\x70\x0F\x1B$)A\x0E\x26\x21\x0F"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x005C,0x007E,
+ 0x4ED9,0x531F,0x4ED9,0x0391 },
+ 12,
+ false,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_2022_CN,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x01\"3De$\\~\x1B$)A\x0E\x26\x21\x1B$*H\x1BN\x22\x22"
+ "\x26\x21\x0F\x0D\x0A\x1B$)A\x0E\x26\x21\x0F"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x005C,0x007E,
+ 0x0391,0x531F,0x0391,0x000D,0x000A,0x0391 },
+ 14,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+ // The following does not work as long as Big5-HKSCS maps to
+ // Unicode PUA instead of Plane 2. Use the next two tests
+ // instead:
+// { RTL_TEXTENCODING_BIG5_HKSCS,
+// RTL_CONSTASCII_STRINGPARAM(
+// "\x01\"3De$~\x88\x56\xF9\xFE\xFA\x5E\xA1\x40\xF9\xD5"),
+// { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x007E,0x0100,
+// 0xFFED,0xD849,0xDD13,0x3000,0x9F98 },
+// 13,
+// true,
+// true,
+// true,
+// false,
+// RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x01\"3De$~\x88\x56\xF9\xFE\xFA\x5E\xA1\x40\xF9\xD5"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x007E,0x0100,
+ 0xFFED,0xE01E,0x3000,0x9F98 },
+ 12,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x01\"3De$~\x88\x56\xF9\xFE\xFA\x5E\xA1\x40\xF9\xD5"),
+ { 0x0001,0x0022,0x0033,0x0044,0x0065,0x0024,0x007E,0x0100,
+ 0xFFED,0xD849,0xDD13,0x3000,0x9F98 },
+ 13,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC6\xA1\xC6\xCF\xC6\xD3\xC6\xD5\xC6\xD7\xC6\xDE\xC6\xDF"
+ "\xC6\xFE\xC7\x40\xC7\x7E\xC7\xA1\xC7\xFE"),
+ { 0x2460,0xF6E0,0xF6E4,0xF6E6,0xF6E8,0xF6EF,0xF6F0,0x3058,
+ 0x3059,0x30A4,0x30A5,0x041A },
+ 12,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM("\x81\x40\x84\xFE"),
+ { 0xEEB8,0xF12B },
+ 2,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x81\x40\x8D\xFE\x8E\x40\xA0\xFE\xC6\xA1\xC8\xFE\xFA\x40"
+ "\xFE\xFE"),
+ { 0xEEB8,0xF6B0,0xE311,0xEEB7,0xF6B1,0xF848,0xE000,0xE310 },
+ 8,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM("\xAD\xC5\x94\x55"),
+ { 0x5029,0x7250 },
+ 2,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM("\xFA\x5F\xA0\xE4"),
+ { 0x5029,0x7250 },
+ 2,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM("\xA0\x40\xA0\x7E\xA0\xA1\xA0\xFE"),
+ { 0xEE1B,0xEE59,0xEE5A,0xEEB7 },
+ 4,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5,
+ RTL_CONSTASCII_STRINGPARAM("\xA1\x45"),
+ { 0x2027 },
+ 1,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC6\xCF\xC6\xD3\xC6\xD5\xC6\xD7\xC6\xDE\xC6\xDF"),
+ { 0x306B,0x306F,0x3071,0x3073,0x307A,0x307B },
+ 6,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC7\xFD\xC7\xFE\xC8\x40\xC8\x7E\xC8\xA1\xC8\xFE"),
+ { 0xF7AA,0xF7AB,0xF7AC,0xF7EA,0xF7EB,0xF848 },
+ 6,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5,
+ RTL_CONSTASCII_STRINGPARAM("\xA0\x40\xA0\x7E\xA0\xA1\xA0\xFE"),
+ { 0xEE1B,0xEE59,0xEE5A,0xEEB7 },
+ 4,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+ { RTL_TEXTENCODING_MS_950,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC6\xA1\xC6\xFE\xC7\x40\xC7\x7E\xC7\xA1\xC7\xFE\xC8\x40"
+ "\xC8\x7E\xC8\xA1\xC8\xFE"),
+ { 0xF6B1,0xF70E,0xF70F,0xF74D,0xF74E,0xF7AB,0xF7AC,0xF7EA,
+ 0xF7EB,0xF848 },
+ 10,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_MS_950,
+ RTL_CONSTASCII_STRINGPARAM("\xA0\x40\xA0\x7E\xA0\xA1\xA0\xFE"),
+ { 0xEE1B,0xEE59,0xEE5A,0xEEB7 },
+ 4,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+ // Test Unicode beyond BMP:
+
+ // FIXME The second m_bForward test (requiring a context) does not
+ // work for UTF7:
+// { RTL_TEXTENCODING_UTF7,
+// RTL_CONSTASCII_STRINGPARAM("+2EndEw-"),
+// { 0xD849,0xDD13 },
+// 2,
+// true,
+// true,
+// true,
+// false,
+// RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\xF0\xA2\x94\x93"),
+ { 0xD849,0xDD13 },
+ 2,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ { RTL_TEXTENCODING_GB_18030,
+ RTL_CONSTASCII_STRINGPARAM("\x95\x39\xC5\x37"),
+ { 0xD849,0xDD13 },
+ 2,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_BIG5_HKSCS,
+ RTL_CONSTASCII_STRINGPARAM("\xFA\x5E"),
+ { 0xD849,0xDD13 },
+ 2,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+ // Test GBK (aka CP936):
+
+ { RTL_TEXTENCODING_GBK,
+ RTL_CONSTASCII_STRINGPARAM("\xFD\x7C\xC1\xFA\xFD\x9B"),
+ { 0x9F76,0x9F99,0x9FA5 },
+ 3,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+ { RTL_TEXTENCODING_MS_936,
+ RTL_CONSTASCII_STRINGPARAM("\xFD\x7C\xC1\xFA\xFD\x9B"),
+ { 0x9F76,0x9F99,0x9FA5 },
+ 3,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ { RTL_TEXTENCODING_GBK,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xFE\x50\xFE\x54\xFE\x55\xFE\x56"
+ "\xFE\x57\xFE\x58\xFE\x5A\xFE\x5B\xFE\x5C\xFE\x5D"
+ "\xFE\x5E\xFE\x5F\xFE\x60\xFE\x62\xFE\x63\xFE\x64"
+ "\xFE\x65\xFE\x68\xFE\x69\xFE\x6A\xFE\x6B"
+ "\xFE\x6E\xFE\x6F\xFE\x70\xFE\x71\xFE\x72"
+ "\xFE\x73\xFE\x74\xFE\x75\xFE\x77\xFE\x78\xFE\x79"
+ "\xFE\x7A\xFE\x7B\xFE\x7C\xFE\x7D\xFE\x80\xFE\x81"
+ "\xFE\x82\xFE\x83\xFE\x84\xFE\x85\xFE\x86\xFE\x87\xFE\x88"
+ "\xFE\x89\xFE\x8A\xFE\x8B\xFE\x8C\xFE\x8D\xFE\x8E\xFE\x8F"
+ "\xFE\x92\xFE\x93\xFE\x94\xFE\x95\xFE\x96"
+ "\xFE\x97\xFE\x98\xFE\x99\xFE\x9A\xFE\x9B\xFE\x9C\xFE\x9D"
+ "\xFE\x9E\xFE\x9F"),
+ { 0x2E81,0x2E84,0x3473,0x3447,0x2E88,0x2E8B,0x359E,0x361A,
+ 0x360E,0x2E8C,0x2E97,0x396E,0x3918,0x39CF,0x39DF,0x3A73,
+ 0x39D0,0x3B4E,0x3C6E,0x3CE0,0x2EA7,0x2EAA,0x4056,0x415F,
+ 0x2EAE,0x4337,0x2EB3,0x2EB6,0x2EB7,0x43B1,0x43AC,0x2EBB,
+ 0x43DD,0x44D6,0x4661,0x464C,0x4723,0x4729,0x477C,0x478D,
+ 0x2ECA,0x4947,0x497A,0x497D,0x4982,0x4983,0x4985,0x4986,
+ 0x499F,0x499B,0x49B7,0x49B6,0x4CA3,0x4C9F,0x4CA0,0x4CA1,
+ 0x4C77,0x4CA2,0x4D13,0x4D14,0x4D15,0x4D16,0x4D17,0x4D18,
+ 0x4D19,0x4DAE },
+ 66,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM("?"),
+ { 0xFF0D },
+ 1,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK },
+#endif
+ // Test of "JIS X 0208 row 13" (taken from CP932; added to
+ // ISO-2022-JP and EUC-JP; 74 of the 83 characters introduce
+ // mappings to new Unicode characters):
+ { RTL_TEXTENCODING_MS_932,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x87\x40\x87\x41\x87\x42\x87\x43\x87\x44\x87\x45\x87\x46"
+ "\x87\x47\x87\x48\x87\x49\x87\x4A\x87\x4B\x87\x4C\x87\x4D"
+ "\x87\x4E\x87\x4F\x87\x50\x87\x51\x87\x52\x87\x53\x87\x54"
+ "\x87\x55\x87\x56\x87\x57\x87\x58\x87\x59\x87\x5A\x87\x5B"
+ "\x87\x5C\x87\x5D\x87\x5F\x87\x60\x87\x61\x87\x62\x87\x63"
+ "\x87\x64\x87\x65\x87\x66\x87\x67\x87\x68\x87\x69\x87\x6A"
+ "\x87\x6B\x87\x6C\x87\x6D\x87\x6E\x87\x6F\x87\x70\x87\x71"
+ "\x87\x72\x87\x73\x87\x74\x87\x75\x87\x7E\x87\x80\x87\x81"
+ "\x87\x82\x87\x83\x87\x84\x87\x85\x87\x86\x87\x87\x87\x88"
+ "\x87\x89\x87\x8A\x87\x8B\x87\x8C\x87\x8D\x87\x8E\x87\x8F"
+ "\x87\x90\x87\x91\x87\x92\x87\x93\x87\x94\x87\x95\x87\x96"
+ "\x87\x97\x87\x98\x87\x99\x87\x9A\x87\x9B\x87\x9C"),
+ { 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,0x2468,
+ 0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F,0x2470,0x2471,
+ 0x2472,0x2473,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,
+ 0x2167,0x2168,0x2169,0x3349,0x3314,0x3322,0x334D,0x3318,0x3327,
+ 0x3303,0x3336,0x3351,0x3357,0x330D,0x3326,0x3323,0x332B,0x334A,
+ 0x333B,0x339C,0x339D,0x339E,0x338E,0x338F,0x33C4,0x33A1,0x337B,
+ 0x301D,0x301F,0x2116,0x33CD,0x2121,0x32A4,0x32A5,0x32A6,0x32A7,
+ 0x32A8,0x3231,0x3232,0x3239,0x337E,0x337D,0x337C,0x2252,0x2261,
+ 0x222B,0x222E,0x2211,0x221A,0x22A5,0x2220,0x221F,0x22BF,0x2235,
+ 0x2229,0x222A },
+ 83,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ { RTL_TEXTENCODING_SHIFT_JIS,
+ RTL_CONSTASCII_STRINGPARAM("\x00\xFA\x6F\xFA\x71"),
+ {0x0000, 0x4F92, 0x4F9A},
+ 3,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_SHIFT_JIS,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x87\x40\x87\x41\x87\x42\x87\x43\x87\x44\x87\x45\x87\x46"
+ "\x87\x47\x87\x48\x87\x49\x87\x4A\x87\x4B\x87\x4C\x87\x4D"
+ "\x87\x4E\x87\x4F\x87\x50\x87\x51\x87\x52\x87\x53\x87\x54"
+ "\x87\x55\x87\x56\x87\x57\x87\x58\x87\x59\x87\x5A\x87\x5B"
+ "\x87\x5C\x87\x5D\x87\x5F\x87\x60\x87\x61\x87\x62\x87\x63"
+ "\x87\x64\x87\x65\x87\x66\x87\x67\x87\x68\x87\x69\x87\x6A"
+ "\x87\x6B\x87\x6C\x87\x6D\x87\x6E\x87\x6F\x87\x70\x87\x71"
+ "\x87\x72\x87\x73\x87\x74\x87\x75\x87\x7E\x87\x80\x87\x81"
+ "\x87\x82\x87\x83\x87\x84\x87\x85\x87\x86\x87\x87\x87\x88"
+ "\x87\x89\x87\x8A\x87\x8B\x87\x8C\x87\x8D\x87\x8E\x87\x8F"
+ "\x87\x90\x87\x91\x87\x92\x87\x93\x87\x94\x87\x95\x87\x96"
+ "\x87\x97\x87\x98\x87\x99\x87\x9A\x87\x9B\x87\x9C"),
+ { 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,0x2468,
+ 0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F,0x2470,0x2471,
+ 0x2472,0x2473,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,
+ 0x2167,0x2168,0x2169,0x3349,0x3314,0x3322,0x334D,0x3318,0x3327,
+ 0x3303,0x3336,0x3351,0x3357,0x330D,0x3326,0x3323,0x332B,0x334A,
+ 0x333B,0x339C,0x339D,0x339E,0x338E,0x338F,0x33C4,0x33A1,0x337B,
+ 0x301D,0x301F,0x2116,0x33CD,0x2121,0x32A4,0x32A5,0x32A6,0x32A7,
+ 0x32A8,0x3231,0x3232,0x3239,0x337E,0x337D,0x337C,0x2252,0x2261,
+ 0x222B,0x222E,0x2211,0x221A,0x22A5,0x2220,0x221F,0x22BF,0x2235,
+ 0x2229,0x222A },
+ 83,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_2022_JP,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x1B$B\x2D\x21\x2D\x22\x2D\x23\x2D\x24\x2D\x25\x2D\x26"
+ "\x2D\x27\x2D\x28\x2D\x29\x2D\x2A\x2D\x2B\x2D\x2C\x2D\x2D"
+ "\x2D\x2E\x2D\x2F\x2D\x30\x2D\x31\x2D\x32\x2D\x33\x2D\x34"
+ "\x2D\x35\x2D\x36\x2D\x37\x2D\x38\x2D\x39\x2D\x3A\x2D\x3B"
+ "\x2D\x3C\x2D\x3D\x2D\x3E\x2D\x40\x2D\x41\x2D\x42\x2D\x43"
+ "\x2D\x44\x2D\x45\x2D\x46\x2D\x47\x2D\x48\x2D\x49\x2D\x4A"
+ "\x2D\x4B\x2D\x4C\x2D\x4D\x2D\x4E\x2D\x4F\x2D\x50\x2D\x51"
+ "\x2D\x52\x2D\x53\x2D\x54\x2D\x55\x2D\x56\x2D\x5F\x2D\x60"
+ "\x2D\x61\x2D\x62\x2D\x63\x2D\x64\x2D\x65\x2D\x66\x2D\x67"
+ "\x2D\x68\x2D\x69\x2D\x6A\x2D\x6B\x2D\x6C\x2D\x6D\x2D\x6E"
+ "\x2D\x6F\x2D\x70\x2D\x71\x2D\x72\x2D\x73\x2D\x74\x2D\x75"
+ "\x2D\x76\x2D\x77\x2D\x78\x2D\x79\x2D\x7A\x2D\x7B\x2D\x7C"
+ "\x1B(B"),
+ { 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,0x2468,
+ 0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F,0x2470,0x2471,
+ 0x2472,0x2473,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,
+ 0x2167,0x2168,0x2169,0x3349,0x3314,0x3322,0x334D,0x3318,0x3327,
+ 0x3303,0x3336,0x3351,0x3357,0x330D,0x3326,0x3323,0x332B,0x334A,
+ 0x333B,0x339C,0x339D,0x339E,0x338E,0x338F,0x33C4,0x33A1,0x337B,
+ 0x301D,0x301F,0x2116,0x33CD,0x2121,0x32A4,0x32A5,0x32A6,0x32A7,
+ 0x32A8,0x3231,0x3232,0x3239,0x337E,0x337D,0x337C,0x2252,0x2261,
+ 0x222B,0x222E,0x2211,0x221A,0x22A5,0x2220,0x221F,0x22BF,0x2235,
+ 0x2229,0x222A },
+ 83,
+ false,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_2022_JP,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x1B$B\x2D\x21\x2D\x22\x2D\x23\x2D\x24\x2D\x25\x2D\x26"
+ "\x2D\x27\x2D\x28\x2D\x29\x2D\x2A\x2D\x2B\x2D\x2C\x2D\x2D"
+ "\x2D\x2E\x2D\x2F\x2D\x30\x2D\x31\x2D\x32\x2D\x33\x2D\x34"
+ "\x2D\x35\x2D\x36\x2D\x37\x2D\x38\x2D\x39\x2D\x3A\x2D\x3B"
+ "\x2D\x3C\x2D\x3D\x2D\x3E\x2D\x40\x2D\x41\x2D\x42\x2D\x43"
+ "\x2D\x44\x2D\x45\x2D\x46\x2D\x47\x2D\x48\x2D\x49\x2D\x4A"
+ "\x2D\x4B\x2D\x4C\x2D\x4D\x2D\x4E\x2D\x4F\x2D\x50\x2D\x51"
+ "\x2D\x52\x2D\x53\x2D\x54\x2D\x55\x2D\x56\x2D\x5F\x2D\x60"
+ "\x2D\x61\x2D\x62\x2D\x63\x2D\x64\x2D\x65\x2D\x66\x2D\x67"
+ "\x2D\x68\x2D\x69\x2D\x6A\x2D\x6B\x2D\x6C\x2D\x6D\x2D\x6E"
+ "\x2D\x6F\x2D\x73\x2D\x74\x2D\x78\x2D\x79\x1B(B"),
+ { 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,0x2468,
+ 0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F,0x2470,0x2471,
+ 0x2472,0x2473,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,
+ 0x2167,0x2168,0x2169,0x3349,0x3314,0x3322,0x334D,0x3318,0x3327,
+ 0x3303,0x3336,0x3351,0x3357,0x330D,0x3326,0x3323,0x332B,0x334A,
+ 0x333B,0x339C,0x339D,0x339E,0x338E,0x338F,0x33C4,0x33A1,0x337B,
+ 0x301D,0x301F,0x2116,0x33CD,0x2121,0x32A4,0x32A5,0x32A6,0x32A7,
+ 0x32A8,0x3231,0x3232,0x3239,0x337E,0x337D,0x337C,0x222E,0x2211,
+ 0x221F,0x22BF },
+ 74,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xAD\xA1\xAD\xA2\xAD\xA3\xAD\xA4\xAD\xA5\xAD\xA6\xAD\xA7"
+ "\xAD\xA8\xAD\xA9\xAD\xAA\xAD\xAB\xAD\xAC\xAD\xAD\xAD\xAE"
+ "\xAD\xAF\xAD\xB0\xAD\xB1\xAD\xB2\xAD\xB3\xAD\xB4\xAD\xB5"
+ "\xAD\xB6\xAD\xB7\xAD\xB8\xAD\xB9\xAD\xBA\xAD\xBB\xAD\xBC"
+ "\xAD\xBD\xAD\xBE\xAD\xC0\xAD\xC1\xAD\xC2\xAD\xC3\xAD\xC4"
+ "\xAD\xC5\xAD\xC6\xAD\xC7\xAD\xC8\xAD\xC9\xAD\xCA\xAD\xCB"
+ "\xAD\xCC\xAD\xCD\xAD\xCE\xAD\xCF\xAD\xD0\xAD\xD1\xAD\xD2"
+ "\xAD\xD3\xAD\xD4\xAD\xD5\xAD\xD6\xAD\xDF\xAD\xE0\xAD\xE1"
+ "\xAD\xE2\xAD\xE3\xAD\xE4\xAD\xE5\xAD\xE6\xAD\xE7\xAD\xE8"
+ "\xAD\xE9\xAD\xEA\xAD\xEB\xAD\xEC\xAD\xED\xAD\xEE\xAD\xEF"
+ "\xAD\xF0\xAD\xF1\xAD\xF2\xAD\xF3\xAD\xF4\xAD\xF5\xAD\xF6"
+ "\xAD\xF7\xAD\xF8\xAD\xF9\xAD\xFA\xAD\xFB\xAD\xFC"),
+ { 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,0x2468,
+ 0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F,0x2470,0x2471,
+ 0x2472,0x2473,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,
+ 0x2167,0x2168,0x2169,0x3349,0x3314,0x3322,0x334D,0x3318,0x3327,
+ 0x3303,0x3336,0x3351,0x3357,0x330D,0x3326,0x3323,0x332B,0x334A,
+ 0x333B,0x339C,0x339D,0x339E,0x338E,0x338F,0x33C4,0x33A1,0x337B,
+ 0x301D,0x301F,0x2116,0x33CD,0x2121,0x32A4,0x32A5,0x32A6,0x32A7,
+ 0x32A8,0x3231,0x3232,0x3239,0x337E,0x337D,0x337C,0x2252,0x2261,
+ 0x222B,0x222E,0x2211,0x221A,0x22A5,0x2220,0x221F,0x22BF,0x2235,
+ 0x2229,0x222A },
+ 83,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xAD\xA1\xAD\xA2\xAD\xA3\xAD\xA4\xAD\xA5\xAD\xA6\xAD\xA7"
+ "\xAD\xA8\xAD\xA9\xAD\xAA\xAD\xAB\xAD\xAC\xAD\xAD\xAD\xAE"
+ "\xAD\xAF\xAD\xB0\xAD\xB1\xAD\xB2\xAD\xB3\xAD\xB4\xAD\xB5"
+ "\xAD\xB6\xAD\xB7\xAD\xB8\xAD\xB9\xAD\xBA\xAD\xBB\xAD\xBC"
+ "\xAD\xBD\xAD\xBE\xAD\xC0\xAD\xC1\xAD\xC2\xAD\xC3\xAD\xC4"
+ "\xAD\xC5\xAD\xC6\xAD\xC7\xAD\xC8\xAD\xC9\xAD\xCA\xAD\xCB"
+ "\xAD\xCC\xAD\xCD\xAD\xCE\xAD\xCF\xAD\xD0\xAD\xD1\xAD\xD2"
+ "\xAD\xD3\xAD\xD4\xAD\xD5\xAD\xD6\xAD\xDF\xAD\xE0\xAD\xE1"
+ "\xAD\xE2\xAD\xE3\xAD\xE4\xAD\xE5\xAD\xE6\xAD\xE7\xAD\xE8"
+ "\xAD\xE9\xAD\xEA\xAD\xEB\xAD\xEC\xAD\xED\xAD\xEE\xAD\xEF"
+ "\xAD\xF3\xAD\xF4\xAD\xF8\xAD\xF9"),
+ { 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,0x2468,
+ 0x2469,0x246A,0x246B,0x246C,0x246D,0x246E,0x246F,0x2470,0x2471,
+ 0x2472,0x2473,0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,
+ 0x2167,0x2168,0x2169,0x3349,0x3314,0x3322,0x334D,0x3318,0x3327,
+ 0x3303,0x3336,0x3351,0x3357,0x330D,0x3326,0x3323,0x332B,0x334A,
+ 0x333B,0x339C,0x339D,0x339E,0x338E,0x338F,0x33C4,0x33A1,0x337B,
+ 0x301D,0x301F,0x2116,0x33CD,0x2121,0x32A4,0x32A5,0x32A6,0x32A7,
+ 0x32A8,0x3231,0x3232,0x3239,0x337E,0x337D,0x337C,0x222E,0x2211,
+ 0x221F,0x22BF },
+ 74,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM("\xB9\xF5"),
+ { 0x9ED2 },
+ 1,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+ // Test ISO-8859-x/MS-125x range 0x80--9F:
+
+ { RTL_TEXTENCODING_ISO_8859_1,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_2,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_3,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_4,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_5,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_6,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_7,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_8,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_9,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_14,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISO_8859_15,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
+ "\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
+ "\x9E\x9F"),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_MS_874,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1250,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1251,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1252,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1253,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1254,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1255,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1256,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1257,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_1258,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,0x0088,
+ 0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,0x0090,0x0091,
+ 0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,0x0098,0x0099,0x009A,
+ 0x009B,0x009C,0x009D,0x009E,0x009F },
+ 32,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_MS_949,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xB0\xA1\xB0\xA2\x81\x41\x81\x42\xB0\xA3\x81\x43\x81\x44"
+ "\xB0\xA4\xB0\xA5\xB0\xA6\xB0\xA7\x81\x45\x81\x46\x81\x47"
+ "\x81\x48\x81\x49\xB0\xA8\xB0\xA9\xB0\xAA\xB0\xAB\xB0\xAC"
+ "\xB0\xAD\xB0\xAE\xB0\xAF\x81\x4A\xB0\xB0\xB0\xB1\xB0\xB2"),
+ { 0xAC00,0xAC01,0xAC02,0xAC03,0xAC04,0xAC05,0xAC06,0xAC07,0xAC08,
+ 0xAC09,0xAC0A,0xAC0B,0xAC0C,0xAC0D,0xAC0E,0xAC0F,0xAC10,0xAC11,
+ 0xAC12,0xAC13,0xAC14,0xAC15,0xAC16,0xAC17,0xAC18,0xAC19,0xAC1A,
+ 0xAC1B },
+ 28,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_MS_949,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC9\xA1\xC9\xA2\xC9\xA3\xC9\xFC\xC9\xFD\xC9\xFE"
+ "\xFE\xA1\xFE\xA2\xFE\xA3\xFE\xFC\xFE\xFD\xFE\xFE"),
+ { 0xE000,0xE001,0xE002,0xE05B,0xE05C,0xE05D,
+ 0xE05E,0xE05F,0xE060,0xE0B9,0xE0BA,0xE0BB },
+ 12,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ { RTL_TEXTENCODING_EUC_KR,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xB0\xA1\xB0\xA2" "\xB0\xA3"
+ "\xB0\xA4\xB0\xA5\xB0\xA6\xB0\xA7"
+ "\xB0\xA8\xB0\xA9\xB0\xAA\xB0\xAB\xB0\xAC"
+ "\xB0\xAD\xB0\xAE\xB0\xAF" "\xB0\xB0\xB0\xB1\xB0\xB2"),
+ { 0xAC00,0xAC01, 0xAC04, 0xAC07,0xAC08,
+ 0xAC09,0xAC0A, 0xAC10,0xAC11,
+ 0xAC12,0xAC13,0xAC14,0xAC15,0xAC16,0xAC17, 0xAC19,0xAC1A,
+ 0xAC1B },
+ 18,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_KR,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xB0\xA1\xB0\xA2" "\xB0\xA3"
+ "\xB0\xA4\xB0\xA5\xB0\xA6\xB0\xA7"
+ "\xB0\xA8\xB0\xA9\xB0\xAA\xB0\xAB\xB0\xAC"
+ "\xB0\xAD\xB0\xAE\xB0\xAF" "\xB0\xB0\xB0\xB1\xB0\xB2"),
+ { 0xAC00,0xAC01,0xAC02,0xAC03,0xAC04,0xAC05,0xAC06,0xAC07,0xAC08,
+ 0xAC09,0xAC0A,0xAC0B,0xAC0C,0xAC0D,0xAC0E,0xAC0F,0xAC10,0xAC11,
+ 0xAC12,0xAC13,0xAC14,0xAC15,0xAC16,0xAC17,0xAC18,0xAC19,0xAC1A,
+ 0xAC1B },
+ 28,
+ true,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_EUC_KR,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC9\xA1\xC9\xA2\xC9\xA3\xC9\xFC\xC9\xFD\xC9\xFE"
+ "\xFE\xA1\xFE\xA2\xFE\xA3\xFE\xFC\xFE\xFD\xFE\xFE"),
+ { 0xE000,0xE001,0xE002,0xE05B,0xE05C,0xE05D,
+ 0xE05E,0xE05F,0xE060,0xE0B9,0xE0BA,0xE0BB },
+ 12,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+ // Test UTF-8:
+
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\x00"),
+ { 0x0000 },
+ 1,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\xEF\xBB\xBF"),
+ { 0xFEFF },
+ 1,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\xEF\xBB\xBF\xEF\xBB\xBF"),
+ { 0xFEFF,0xFEFF },
+ 2,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\xEF\xBB\xBF"),
+ { 0 },
+ 0,
+ false,
+ true,
+ true,
+ true,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\xEF\xBB\xBF\xEF\xBB\xBF"),
+ { 0xFEFF },
+ 1,
+ false,
+ true,
+ true,
+ true,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\x01\x02\x7E\x7F"),
+ { 0x0001,0x0002,0x007E,0x007F },
+ 4,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_UTF8,
+ RTL_CONSTASCII_STRINGPARAM("\xEF\xBF\xBF"),
+ {0xFFFF},
+ 1,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+ // Test Java UTF-8:
+
+ { RTL_TEXTENCODING_JAVA_UTF8,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xEF\xBB\xBF\xC0\x80\x01\x20\x41\x7F\xED\xA0\x80"
+ "\xED\xB0\x80"),
+ { 0xFEFF,0x0000,0x0001,0x0020,0x0041,0x007F,0xD800,0xDC00 },
+ 8,
+ false,
+ true,
+ true,
+ true,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ // Bug #112949#:
+ { RTL_TEXTENCODING_SHIFT_JIS,
+ RTL_CONSTASCII_STRINGPARAM("\x81\x63"),
+ { 0x2026 },
+ 1,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_SHIFT_JIS,
+ RTL_CONSTASCII_STRINGPARAM("\xA0\xFD\xFE\xFF"),
+ { 0x00A0, 0x00A9, 0x2122, 0x2026 },
+ 4,
+ false,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_SHIFT_JIS,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x00A0, 0x00A9, 0x2122 },
+ 3,
+ false,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+#endif
+ { RTL_TEXTENCODING_MS_932,
+ RTL_CONSTASCII_STRINGPARAM("\x81\x63"),
+ { 0x2026 },
+ 1,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_MS_932,
+ RTL_CONSTASCII_STRINGPARAM("\xA0\xFD\xFE\xFF"),
+ { 0x00A0, 0x00A9, 0x2122, 0x2026 },
+ 4,
+ false,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_MS_932,
+ RTL_CONSTASCII_STRINGPARAM(""),
+ { 0x00A0, 0x00A9, 0x2122 },
+ 3,
+ false,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE },
+ { RTL_TEXTENCODING_APPLE_JAPANESE,
+ RTL_CONSTASCII_STRINGPARAM("\xA0\xFD\xFE\x81\x63"),
+ { 0x00A0, 0x00A9, 0x2122, 0x2026 },
+ 4,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_APPLE_JAPANESE,
+ RTL_CONSTASCII_STRINGPARAM("\xFF"),
+ { 0x2026 },
+ 1,
+ false,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+ { RTL_TEXTENCODING_ADOBE_STANDARD,
+ RTL_CONSTASCII_STRINGPARAM("\x20\x2D\xA4\xB4\xC5"),
+ { 0x0020, 0x002D, 0x2215, 0x00B7, 0x00AF },
+ 5,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ADOBE_STANDARD,
+ RTL_CONSTASCII_STRINGPARAM("\x20\x2D\xA4\xB4\xC5"),
+ { 0x00A0, 0x00AD, 0x2044, 0x2219, 0x02C9 },
+ 5,
+ false,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+ { RTL_TEXTENCODING_ADOBE_SYMBOL,
+ RTL_CONSTASCII_STRINGPARAM("\x20\x44\x57\x6D\xA4"),
+ { 0x0020, 0x0394, 0x03A9, 0x03BC, 0x2215 },
+ 5,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ADOBE_SYMBOL,
+ RTL_CONSTASCII_STRINGPARAM("\x20\x44\x57\x6D\xA4"),
+ { 0x00A0, 0x2206, 0x2126, 0x00B5, 0x2044 },
+ 5,
+ false,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ // Bug #i62310#:
+ { RTL_TEXTENCODING_SHIFT_JIS,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xF0\x40\xF0\x7E\xF0\x80\xF0\xFC\xF1\x40\xF9\xFC"),
+ { 0xE000, 0xE03E, 0xE03F, 0xE0BB, 0xE0BC, 0xE757 },
+ 6,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+ // Bug #i73103#:
+ { RTL_TEXTENCODING_MS_1258,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC0\x41\xDE\xE3\xD2\xD4\xEC\xFD\xF2"),
+ { 0x00C0, 0x0041, 0x0303, 0x0103, 0x0309, 0x00D4, 0x0301, 0x01B0,
+ 0x0323 },
+ 9,
+ true,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_MS_1258,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xC0\x41\xDE\xE3\xD2\xD4\xEC\xFD\xF2"),
+ { 0x00C0, 0x00C3, 0x1EB3, 0x1ED0, 0x1EF1 },
+ 5,
+ false,
+ false,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#if WITH_LOCALE_ALL || WITH_LOCALE_FOR_SCRIPT_Deva
+ { RTL_TEXTENCODING_ISCII_DEVANAGARI,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\xD7\xE6\x20\xD4\xCF\xE8\xD6\x20"
+ "\xC8\xD8\xD1\xE1\x20\xB3\xCA\xDC"
+ "\xCF\xC4\xDA\xD7\x20\xD8\xDB\xA2"
+ "\xC4\xDE\x20\xB1\xCF\x20\xCC\xDD"
+ "\xD7\xD1\xCC\xDA\xC6\x20\xC4\xE5"
+ "\xC6\xE5\xA2\x20\xB3\xE1\x20\xB3"
+ "\xBD\xE8\xBD\xCF\xC8\xC6\x20\xB3"
+ "\xE5\x20\xC9\xBD\xB3\xDA\xCF\x20"
+ "\xB8\xDD\xB3\xE1\x20\xC3\xE1\x20"
+ "\xEA"),
+ { 0x0938, 0x094C, 0x0020, 0x0935, 0x0930, 0x094D, 0x0937, 0x0020,
+ 0x092A, 0x0939, 0x0932, 0x0947, 0x0020, 0x0915, 0x092C, 0x0940,
+ 0x0930, 0x0926, 0x093E, 0x0938, 0x0020, 0x0939, 0x093F, 0x0902,
+ 0x0926, 0x0942, 0x0020, 0x0914, 0x0930, 0x0020, 0x092E, 0x0941,
+ 0x0938, 0x0932, 0x092E, 0x093E, 0x0928, 0x0020, 0x0926, 0x094B,
+ 0x0928, 0x094B, 0x0902, 0x0020, 0x0915, 0x0947, 0x0020, 0x0915,
+ 0x091F, 0x094D, 0x091F, 0x0930, 0x092A, 0x0928, 0x0020, 0x0915,
+ 0x094B, 0x0020, 0x092B, 0x091F, 0x0915, 0x093E, 0x0930, 0x0020,
+ 0x091A, 0x0941, 0x0915, 0x0947, 0x0020, 0x0925, 0x0947, 0x0020,
+ 0x0964 },
+ 73,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_ISCII_DEVANAGARI,
+ RTL_CONSTASCII_STRINGPARAM("\xE8\xE8\xE8\xE9\xA1\xE9\xEA\xE9"),
+ { 0x094D, 0x200C, 0x094D, 0x200D, 0x0950, 0x93D },
+ 6,
+ false,
+ true,
+ true,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR }
+#endif
+ };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ doComplexCharSetTest(data[i]);
+ }
+}
+
+void Test::testComplexCut() {
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja || WITH_LOCALE_zh
+ static ComplexCharSetTest const data[]
+ = {
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM("\xA1"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM("\x8E"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM("\x8F"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_JP,
+ RTL_CONSTASCII_STRINGPARAM("\x8F\xA1"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ { RTL_TEXTENCODING_EUC_CN,
+ RTL_CONSTASCII_STRINGPARAM("\xA1"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+#endif
+/* ,
+ { RTL_TEXTENCODING_EUC_TW,
+ RTL_CONSTASCII_STRINGPARAM("\xA1"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_TW,
+ RTL_CONSTASCII_STRINGPARAM("\x8E"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_TW,
+ RTL_CONSTASCII_STRINGPARAM("\x8E\xA1"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR },
+ { RTL_TEXTENCODING_EUC_TW,
+ RTL_CONSTASCII_STRINGPARAM("\x8E\xA1\xA1"),
+ { 0 },
+ 0,
+ true,
+ true,
+ false,
+ false,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR } */ };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ doComplexCharSetCutTest(data[i]);
+ }
+#endif
+}
+
+void Test::testInvalidUtf7() {
+ auto const converter = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF7);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\x80"), buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+}
+
+void Test::testInvalidUtf8() {
+ // UTF-8, invalid bytes:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\x80\xBF\xFE\xFF"),
+ buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(4), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD\uFFFD\uFFFD\uFFFD"),
+ OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(4), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, non-shortest two-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\xC0\x80"),
+ buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(2), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, cut two-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\xC0"), buf,
+ TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(0), size);
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL, info);
+ CPPUNIT_ASSERT(converted <= 1);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, non-shortest three-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\xE0\x9F\xBF"),
+ buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(3), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, cut three-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\xE0\x80"), buf,
+ TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(0), size);
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL, info);
+ CPPUNIT_ASSERT(converted <= 2);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, cut three-byte sequence followed by more:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\xE0\x80."), buf,
+ TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(2), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD."), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(3), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, surrogates:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr,
+ RTL_CONSTASCII_STRINGPARAM("\xED\xA0\x80\xED\xB0\x80"), buf,
+ TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(2), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(6), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, non-shortest four-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\xF0\x8F\xBF\xBF"),
+ buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(4), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, too-large four-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\xF4\x90\x80\x80"),
+ buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(4), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, five-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr,
+ RTL_CONSTASCII_STRINGPARAM("\xFB\xBF\xBF\xBF\xBF"),
+ buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(5), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // UTF-8, six-byte sequence:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr,
+ RTL_CONSTASCII_STRINGPARAM("\xFD\xBF\xBF\xBF\xBF\xBF"),
+ buf, TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(6), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // Java UTF-8, U+0000:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_JAVA_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, RTL_CONSTASCII_STRINGPARAM("\0"), buf,
+ TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+ // Java UTF-8, U+10000:
+ {
+ auto const converter = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_JAVA_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ constexpr OStringLiteral input(u8"\U00010000");
+ sal_Unicode buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertTextToUnicode(
+ converter, nullptr, input.getStr(), input.getLength(), buf,
+ TEST_STRING_SIZE,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT
+ | RTL_TEXTTOUNICODE_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), size);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString(u"\uFFFD"), OUString(buf, sal_Int32(size)));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(4), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+ }
+}
+
+void Test::testInvalidUnicode() {
+ auto const converter = rtl_createUnicodeToTextConverter(RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT(converter != nullptr);
+ sal_Unicode const input[] = {0xDC00}; // lone low surrogate
+ char buf[TEST_STRING_SIZE];
+ sal_uInt32 info;
+ sal_Size converted;
+ auto const size = rtl_convertUnicodeToText(
+ converter, nullptr, input, SAL_N_ELEMENTS(input), buf, TEST_STRING_SIZE,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_FLUSH),
+ &info, &converted);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(0), size);
+ CPPUNIT_ASSERT_EQUAL(RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_INVALID, info);
+ CPPUNIT_ASSERT_EQUAL(sal_Size(1), converted);
+ rtl_destroyTextToUnicodeConverter(converter);
+}
+
+void Test::testSRCBUFFERTOSMALL() {
+ rtl_TextToUnicodeConverter cv = rtl_createTextToUnicodeConverter(
+ RTL_TEXTENCODING_EUC_JP);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeConverter(EUC-JP) failed",
+ cv != nullptr);
+ rtl_TextToUnicodeContext cx = rtl_createTextToUnicodeContext(cv);
+ CPPUNIT_ASSERT_MESSAGE("rtl_createTextToUnicodeContext failed", cx != nullptr);
+ char src = '\xA1';
+ sal_Unicode dst[10];
+ sal_uInt32 info;
+ sal_Size cvt;
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Size(0),
+ rtl_convertTextToUnicode(
+ cv, cx, &src, 1, dst, SAL_N_ELEMENTS(dst),
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR),
+ &info, &cvt));
+ CPPUNIT_ASSERT_EQUAL(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL, info);
+ CPPUNIT_ASSERT(cvt <= 1);
+ rtl_destroyTextToUnicodeContext(cv, cx);
+ rtl_destroyTextToUnicodeConverter(cv);
+}
+
+void Test::testMime() {
+ struct Data {
+ char const * mime;
+ rtl_TextEncoding encoding;
+ bool reverse;
+ };
+ static Data const data[] = {
+ { "GBK", RTL_TEXTENCODING_GBK, false },
+ { "CP936", RTL_TEXTENCODING_GBK, false },
+ { "MS936", RTL_TEXTENCODING_GBK, false },
+ { "windows-936", RTL_TEXTENCODING_GBK, false },
+
+ { "GB18030", RTL_TEXTENCODING_GB_18030, false },
+
+ { "TIS-620", RTL_TEXTENCODING_TIS_620, true },
+ { "ISO-8859-11", RTL_TEXTENCODING_TIS_620, false }, // not registered
+
+ { "CP874", RTL_TEXTENCODING_MS_874, false }, // not registered
+ { "MS874", RTL_TEXTENCODING_MS_874, false }, // not registered
+ { "windows-874", RTL_TEXTENCODING_MS_874, true }, // not registered
+
+ { "ISO_8859-8:1988", RTL_TEXTENCODING_ISO_8859_8, false },
+ { "iso-ir-138", RTL_TEXTENCODING_ISO_8859_8, false },
+ { "ISO_8859-8", RTL_TEXTENCODING_ISO_8859_8, false },
+ { "ISO-8859-8", RTL_TEXTENCODING_ISO_8859_8, true },
+ { "hebrew", RTL_TEXTENCODING_ISO_8859_8, false },
+ { "csISOLatinHebrew", RTL_TEXTENCODING_ISO_8859_8, false },
+
+ { "windows-1255", RTL_TEXTENCODING_MS_1255, true },
+
+ { "IBM862", RTL_TEXTENCODING_IBM_862, true },
+ { "cp862", RTL_TEXTENCODING_IBM_862, false },
+ { "862", RTL_TEXTENCODING_IBM_862, false },
+ { "csPC862LatinHebrew", RTL_TEXTENCODING_IBM_862, false },
+
+ { "ISO_8859-6:1987", RTL_TEXTENCODING_ISO_8859_6, false },
+ { "iso-ir-127", RTL_TEXTENCODING_ISO_8859_6, false },
+ { "ISO_8859-6", RTL_TEXTENCODING_ISO_8859_6, false },
+ { "ISO-8859-6", RTL_TEXTENCODING_ISO_8859_6, true },
+ { "ECMA-114", RTL_TEXTENCODING_ISO_8859_6, false },
+ { "ASMO-708", RTL_TEXTENCODING_ISO_8859_6, false },
+ { "arabic", RTL_TEXTENCODING_ISO_8859_6, false },
+ { "csISOLatinArabic", RTL_TEXTENCODING_ISO_8859_6, false },
+
+ { "windows-1256", RTL_TEXTENCODING_MS_1256, true },
+
+ { "IBM864", RTL_TEXTENCODING_IBM_864, true },
+ { "cp864", RTL_TEXTENCODING_IBM_864, false },
+ { "csIBM864", RTL_TEXTENCODING_IBM_864, false },
+
+ { "KOI8-R", RTL_TEXTENCODING_KOI8_R, false },
+ { "csKOI8R", RTL_TEXTENCODING_KOI8_R, false },
+ { "koi8-r", RTL_TEXTENCODING_KOI8_R, true },
+
+ { "KOI8-U", RTL_TEXTENCODING_KOI8_U, true },
+
+ { "IBM860", RTL_TEXTENCODING_IBM_860, true },
+ { "cp860", RTL_TEXTENCODING_IBM_860, false },
+ { "860", RTL_TEXTENCODING_IBM_860, false },
+ { "csIBM860", RTL_TEXTENCODING_IBM_860, false },
+
+ { "IBM861", RTL_TEXTENCODING_IBM_861, true },
+ { "cp861", RTL_TEXTENCODING_IBM_861, false },
+ { "861", RTL_TEXTENCODING_IBM_861, false },
+ { "cp-is", RTL_TEXTENCODING_IBM_861, false },
+ { "csIBM861", RTL_TEXTENCODING_IBM_861, false },
+
+ { "IBM863", RTL_TEXTENCODING_IBM_863, true },
+ { "cp863", RTL_TEXTENCODING_IBM_863, false },
+ { "863", RTL_TEXTENCODING_IBM_863, false },
+ { "csIBM863", RTL_TEXTENCODING_IBM_863, false },
+
+ { "IBM865", RTL_TEXTENCODING_IBM_865, true },
+ { "cp865", RTL_TEXTENCODING_IBM_865, false },
+ { "865", RTL_TEXTENCODING_IBM_865, false },
+ { "csIBM865", RTL_TEXTENCODING_IBM_865, false },
+
+ { "Latin-9", RTL_TEXTENCODING_ISO_8859_15, false },
+
+ { "KS_C_5601-1987", RTL_TEXTENCODING_MS_949, false },
+ { "iso-ir-149", RTL_TEXTENCODING_MS_949, false },
+ { "KS_C_5601-1989", RTL_TEXTENCODING_MS_949, false },
+ { "KSC_5601", RTL_TEXTENCODING_MS_949, false },
+ { "korean", RTL_TEXTENCODING_MS_949, false },
+ { "csKSC56011987", RTL_TEXTENCODING_MS_949, false },
+ { nullptr, RTL_TEXTENCODING_MS_949, true },
+
+ { "Adobe-Standard-Encoding", RTL_TEXTENCODING_ADOBE_STANDARD, false },
+ { "csAdobeStandardEncoding", RTL_TEXTENCODING_ADOBE_STANDARD, false },
+ { "Adobe-Symbol-Encoding", RTL_TEXTENCODING_ADOBE_SYMBOL, false },
+ { "csHPPSMath", RTL_TEXTENCODING_ADOBE_SYMBOL, false },
+
+ { "PTCP154", RTL_TEXTENCODING_PT154, true },
+ { "csPTCP154", RTL_TEXTENCODING_PT154, false },
+ { "PT154", RTL_TEXTENCODING_PT154, false },
+ { "CP154", RTL_TEXTENCODING_PT154, false },
+ { "Cyrillic-Asian", RTL_TEXTENCODING_PT154, false }
+ };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ if (data[i].mime == nullptr) {
+ OSL_ASSERT(data[i].reverse);
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast< char const * >(nullptr),
+ rtl_getMimeCharsetFromTextEncoding(data[i].encoding));
+ } else {
+ CPPUNIT_ASSERT_EQUAL(
+ data[i].encoding,
+ rtl_getTextEncodingFromMimeCharset(data[i].mime));
+ if (data[i].reverse) {
+ CPPUNIT_ASSERT_EQUAL(
+ OString(data[i].mime),
+ OString(
+ rtl_getMimeCharsetFromTextEncoding(data[i].encoding)));
+ }
+ }
+ }
+}
+
+void Test::testWindows() {
+ struct Data {
+ sal_uInt32 codePage;
+ rtl_TextEncoding encoding;
+ bool reverse;
+ };
+ static Data const data[] = {
+ { 42, RTL_TEXTENCODING_SYMBOL, true },
+ { 437, RTL_TEXTENCODING_IBM_437, true },
+ { 708, RTL_TEXTENCODING_ISO_8859_6, false },
+ { 737, RTL_TEXTENCODING_IBM_737, true },
+ { 775, RTL_TEXTENCODING_IBM_775, true },
+ { 850, RTL_TEXTENCODING_IBM_850, true },
+ { 852, RTL_TEXTENCODING_IBM_852, true },
+ { 855, RTL_TEXTENCODING_IBM_855, true },
+ { 857, RTL_TEXTENCODING_IBM_857, true },
+ { 860, RTL_TEXTENCODING_IBM_860, true },
+ { 861, RTL_TEXTENCODING_IBM_861, true },
+ { 862, RTL_TEXTENCODING_IBM_862, true },
+ { 863, RTL_TEXTENCODING_IBM_863, true },
+ { 864, RTL_TEXTENCODING_IBM_864, true },
+ { 865, RTL_TEXTENCODING_IBM_865, true },
+ { 866, RTL_TEXTENCODING_IBM_866, true },
+ { 869, RTL_TEXTENCODING_IBM_869, true },
+ { 874, RTL_TEXTENCODING_MS_874, true },
+ { 932, RTL_TEXTENCODING_MS_932, true },
+ { 936, RTL_TEXTENCODING_MS_936, true },
+ { 949, RTL_TEXTENCODING_MS_949, true },
+ { 950, RTL_TEXTENCODING_MS_950, true },
+ { 1250, RTL_TEXTENCODING_MS_1250, true },
+ { 1251, RTL_TEXTENCODING_MS_1251, true },
+ { 1252, RTL_TEXTENCODING_MS_1252, true },
+ { 1253, RTL_TEXTENCODING_MS_1253, true },
+ { 1254, RTL_TEXTENCODING_MS_1254, true },
+ { 1255, RTL_TEXTENCODING_MS_1255, true },
+ { 1256, RTL_TEXTENCODING_MS_1256, true },
+ { 1257, RTL_TEXTENCODING_MS_1257, true },
+ { 1258, RTL_TEXTENCODING_MS_1258, true },
+ { 1361, RTL_TEXTENCODING_MS_1361, true },
+ { 10000, RTL_TEXTENCODING_APPLE_ROMAN, true },
+ { 10001, RTL_TEXTENCODING_APPLE_JAPANESE, true },
+ { 10002, RTL_TEXTENCODING_APPLE_CHINTRAD, true },
+ { 10003, RTL_TEXTENCODING_APPLE_KOREAN, true },
+ { 10004, RTL_TEXTENCODING_APPLE_ARABIC, true },
+ { 10005, RTL_TEXTENCODING_APPLE_HEBREW, true },
+ { 10006, RTL_TEXTENCODING_APPLE_GREEK, true },
+ { 10007, RTL_TEXTENCODING_APPLE_CYRILLIC, true },
+ { 10008, RTL_TEXTENCODING_APPLE_CHINSIMP, true },
+ { 10010, RTL_TEXTENCODING_APPLE_ROMANIAN, true },
+ { 10017, RTL_TEXTENCODING_APPLE_UKRAINIAN, true },
+ { 10029, RTL_TEXTENCODING_APPLE_CENTEURO, true },
+ { 10079, RTL_TEXTENCODING_APPLE_ICELAND, true },
+ { 10081, RTL_TEXTENCODING_APPLE_TURKISH, true },
+ { 10082, RTL_TEXTENCODING_APPLE_CROATIAN, true },
+ { 20127, RTL_TEXTENCODING_ASCII_US, true },
+ { 20866, RTL_TEXTENCODING_KOI8_R, true },
+ { 21866, RTL_TEXTENCODING_KOI8_U, true },
+ { 28591, RTL_TEXTENCODING_ISO_8859_1, true },
+ { 28592, RTL_TEXTENCODING_ISO_8859_2, true },
+ { 28593, RTL_TEXTENCODING_ISO_8859_3, true },
+ { 28594, RTL_TEXTENCODING_ISO_8859_4, true },
+ { 28595, RTL_TEXTENCODING_ISO_8859_5, true },
+ { 28596, RTL_TEXTENCODING_ISO_8859_6, true },
+ { 28597, RTL_TEXTENCODING_ISO_8859_7, true },
+ { 28598, RTL_TEXTENCODING_ISO_8859_8, true },
+ { 28599, RTL_TEXTENCODING_ISO_8859_9, true },
+ { 28605, RTL_TEXTENCODING_ISO_8859_15, true },
+ { 50220, RTL_TEXTENCODING_ISO_2022_JP, true },
+ { 50225, RTL_TEXTENCODING_ISO_2022_KR, true },
+ { 51932, RTL_TEXTENCODING_EUC_JP, true },
+ { 51936, RTL_TEXTENCODING_EUC_CN, true },
+ { 51949, RTL_TEXTENCODING_EUC_KR, true },
+ { 65000, RTL_TEXTENCODING_UTF7, true },
+ { 65001, RTL_TEXTENCODING_UTF8, true },
+ { 1200, RTL_TEXTENCODING_DONTKNOW, false }, // UTF_16LE
+ { 1201, RTL_TEXTENCODING_DONTKNOW, false }, // UTF_16LE
+ { 0, RTL_TEXTENCODING_DONTKNOW, true },
+ { 0, RTL_TEXTENCODING_UCS4, true },
+ { 0, RTL_TEXTENCODING_UCS2, true },
+ { 57002, RTL_TEXTENCODING_ISCII_DEVANAGARI, true }
+ };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ OSL_ASSERT(data[i].codePage != 0 || data[i].reverse);
+ if (data[i].codePage != 0) {
+ CPPUNIT_ASSERT_EQUAL(
+ data[i].encoding,
+ rtl_getTextEncodingFromWindowsCodePage(data[i].codePage));
+ }
+ if (data[i].reverse) {
+ CPPUNIT_ASSERT_EQUAL(
+ data[i].codePage,
+ rtl_getWindowsCodePageFromTextEncoding(data[i].encoding));
+ }
+ }
+}
+
+void Test::testInfo() {
+ struct Data {
+ rtl_TextEncoding encoding;
+ sal_uInt32 flag;
+ bool value;
+ };
+ static Data const data[] = {
+#if WITH_LOCALE_ALL || WITH_LOCALE_ja
+ { RTL_TEXTENCODING_APPLE_JAPANESE, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_EUC_JP, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_ISO_2022_JP, RTL_TEXTENCODING_INFO_CONTEXT, true },
+ { RTL_TEXTENCODING_ISO_2022_JP, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_SHIFT_JIS, RTL_TEXTENCODING_INFO_ASCII, false },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_ko
+ { RTL_TEXTENCODING_APPLE_KOREAN, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_EUC_KR, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_ISO_2022_KR, RTL_TEXTENCODING_INFO_CONTEXT, true },
+ { RTL_TEXTENCODING_ISO_2022_KR, RTL_TEXTENCODING_INFO_ASCII, false },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ { RTL_TEXTENCODING_APPLE_CHINTRAD, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_BIG5, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_BIG5_HKSCS, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_EUC_CN, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_EUC_TW, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_GBK, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_GB_18030, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_GB_18030, RTL_TEXTENCODING_INFO_UNICODE, true },
+ { RTL_TEXTENCODING_ISO_2022_CN, RTL_TEXTENCODING_INFO_CONTEXT, true },
+ { RTL_TEXTENCODING_ISO_2022_CN, RTL_TEXTENCODING_INFO_ASCII, false },
+#endif
+#if WITH_LOCALE_ALL || WITH_LOCALE_FOR_SCRIPT_Deva
+ { RTL_TEXTENCODING_ISCII_DEVANAGARI, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_ISCII_DEVANAGARI, RTL_TEXTENCODING_INFO_MIME, false },
+#endif
+ { RTL_TEXTENCODING_MS_1361, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_MS_874, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_MS_932, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_MS_936, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_MS_949, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_MS_950, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_KOI8_R, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_KOI8_R, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_KOI8_U, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_KOI8_U, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_IBM_860, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_IBM_861, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_IBM_863, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_IBM_865, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_ADOBE_STANDARD, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_ADOBE_STANDARD, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_ADOBE_STANDARD, RTL_TEXTENCODING_INFO_SYMBOL, false },
+ { RTL_TEXTENCODING_ADOBE_SYMBOL, RTL_TEXTENCODING_INFO_ASCII, false },
+ { RTL_TEXTENCODING_ADOBE_SYMBOL, RTL_TEXTENCODING_INFO_MIME, true },
+ { RTL_TEXTENCODING_ADOBE_SYMBOL, RTL_TEXTENCODING_INFO_SYMBOL, true },
+ { RTL_TEXTENCODING_PT154, RTL_TEXTENCODING_INFO_ASCII, true },
+ { RTL_TEXTENCODING_PT154, RTL_TEXTENCODING_INFO_MIME, true }
+ };
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ rtl_TextEncodingInfo info;
+ info.StructSize = sizeof info;
+ CPPUNIT_ASSERT(rtl_getTextEncodingInfo(data[i].encoding, &info));
+ CPPUNIT_ASSERT_EQUAL(data[i].value, ((info.Flags & data[i].flag) != 0));
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/uri/rtl_Uri.cxx b/sal/qa/rtl/uri/rtl_Uri.cxx
new file mode 100644
index 000000000..1084926c6
--- /dev/null
+++ b/sal/qa/rtl/uri/rtl_Uri.cxx
@@ -0,0 +1,79 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdlib.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/uri.hxx>
+#include <osl/thread.h>
+#include <osl/file.hxx>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+namespace Stringtest
+{
+
+ class Convert : public CppUnit::TestFixture
+ {
+ public:
+ OString convertToOString(OUString const& _suStr)
+ {
+ return OUStringToOString(_suStr, osl_getThreadTextEncoding()/*RTL_TEXTENCODING_ASCII_US*/);
+ }
+
+ void showContent(OUString const& _suStr)
+ {
+ OString sStr = convertToOString(_suStr);
+ printf("%s\n", sStr.getStr());
+ }
+
+ void test_FromUTF8_001()
+ {
+ // string --> ustring
+ OUString suStrUTF8 = OStringToOUString("h%C3%A4llo", RTL_TEXTENCODING_ASCII_US);
+
+ // UTF8 --> real ustring
+ OUString suStr_UriDecodeToIuri = rtl::Uri::decode(suStrUTF8, rtl_UriDecodeToIuri, RTL_TEXTENCODING_UTF8);
+ showContent(suStr_UriDecodeToIuri);
+
+ // string --> ustring
+ OString sStr("h\xE4llo", strlen("h\xE4llo"));
+ OUString suString = OStringToOUString(sStr, RTL_TEXTENCODING_ISO_8859_15);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Strings must be equal", suString, suStr_UriDecodeToIuri);
+
+ // ustring --> ustring (UTF8)
+ OUString suStr2 = rtl::Uri::encode(suStr_UriDecodeToIuri, rtl_UriCharClassUnoParamValue, rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8);
+ showContent(suStr2);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Strings must be equal", suStr2, suStrUTF8);
+ // suStr should be equal to suStr2
+ }
+
+ CPPUNIT_TEST_SUITE( Convert );
+ CPPUNIT_TEST( test_FromUTF8_001 );
+ CPPUNIT_TEST_SUITE_END( );
+ };
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION( Stringtest::Convert );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/uri/rtl_testuri.cxx b/sal/qa/rtl/uri/rtl_testuri.cxx
new file mode 100644
index 000000000..fc45ba238
--- /dev/null
+++ b/sal/qa/rtl/uri/rtl_testuri.cxx
@@ -0,0 +1,514 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_locales.h>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <cstddef>
+#include <stdio.h>
+
+namespace {
+
+struct Test: public CppUnit::TestFixture {
+ void test_Uri();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(test_Uri);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::test_Uri() {
+ rtl_UriCharClass const eFirstCharClass = rtl_UriCharClassNone;
+ rtl_UriCharClass const eLastCharClass = rtl_UriCharClassUnoParamValue;
+
+ OUString aText1;
+ OUString aText2;
+
+ // Check that all characters map back to themselves when encoded/decoded:
+
+ aText1 = OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ "\x20\x21\x22\x23\x24\x25\x26\x27"
+ "\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F"
+ "\x30\x31\x32\x33\x34\x35\x36\x37"
+ "\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
+ "\x40\x41\x42\x43\x44\x45\x46\x47"
+ "\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F"
+ "\x50\x51\x52\x53\x54\x55\x56\x57"
+ "\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F"
+ "\x60\x61\x62\x63\x64\x65\x66\x67"
+ "\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F"
+ "\x70\x71\x72\x73\x74\x75\x76\x77"
+ "\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F"));
+ aText2 = aText1;
+ for (rtl_UriCharClass eCharClass = eFirstCharClass;
+ eCharClass <= eLastCharClass;
+ eCharClass = static_cast< rtl_UriCharClass >(eCharClass + 1))
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 1",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ASCII_US));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 2",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ASCII_US));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 3",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ISO_8859_1));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 4",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ISO_8859_1));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 5",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 6",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8));
+ }
+
+ aText1 = OUString(
+ ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F"
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
+ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F"
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F"
+ "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F"
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F"
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
+ "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
+ "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF"
+ "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"
+ "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF"
+ "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF"
+ "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"),
+ 256, RTL_TEXTENCODING_ISO_8859_1);
+ aText2 = aText1;
+ for (rtl_UriCharClass eCharClass = eFirstCharClass;
+ eCharClass <= eLastCharClass;
+ eCharClass = static_cast< rtl_UriCharClass >(eCharClass + 1))
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 7",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ISO_8859_1));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 8",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_ISO_8859_1),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ISO_8859_1));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 9",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_UTF8),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 10",
+ aText2,
+ rtl::Uri::decode(
+ rtl::Uri::encode(
+ aText1, eCharClass, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_UTF8),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8));
+ }
+
+ // Check surrogate handling:
+
+ aText1 = u"\xD800" // %ED%A0%80
+ u"\U000103FF" // 0xD800,0xDFFF -> %F0%90%8F%BF
+ u"\xDFFF" // %ED%BF%BF
+ u"A"; // A
+ aText2 = "%ED%A0%80" "%F0%90%8F%BF" "%ED%BF%BF" "A";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 11",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 12",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeKeepEscapes,
+ RTL_TEXTENCODING_UTF8));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 13",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_UTF8));
+
+ aText1 = "%ed%a0%80" "%f0%90%8f%bf" "%ed%bf%bf" "A";
+ aText2 = u"%ED%A0%80" u"\U000103FF" u"%ED%BF%BF" u"A";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 14",
+ aText2,
+ rtl::Uri::decode(aText1, rtl_UriDecodeToIuri, RTL_TEXTENCODING_UTF8));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 15",
+ aText2,
+ rtl::Uri::decode(
+ aText1, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8));
+
+ // Check UTF-8 handling:
+
+ aText1 = "%E0%83%BF";
+ // \U+00FF encoded with three instead of two bytes
+ aText2 = aText1;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 16",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_UTF8));
+
+ aText1 = "%EF%BF%BF";
+ // \U+FFFF is no legal character
+ aText2 = aText1;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 17",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_UTF8));
+
+ // Check IURI handling:
+
+ aText1 = "%30%C3%BF";
+ aText2 = u"%30\u00FF";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 18",
+ aText2,
+ rtl::Uri::decode(aText1, rtl_UriDecodeToIuri, RTL_TEXTENCODING_UTF8));
+
+ // Check modified rtl_UriCharClassUnoParamValue (removed '[' and ']'):
+
+ aText1 = "[]%5B%5D";
+ aText2 = "%5B%5D%5B%5D";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 19",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUnoParamValue, rtl_UriEncodeCheckEscapes,
+ RTL_TEXTENCODING_ASCII_US));
+
+ // Check Uri::convertRelToAbs:
+
+ struct RelToAbsTest
+ {
+ char const * pBase;
+ char const * pRel;
+ char const * pAbs;
+ };
+ static RelToAbsTest const aRelToAbsTest[]
+ = { // The following tests are taken from RFC 3986:
+ { "http://a/b/c/d;p?q", "g:h", "g:h" },
+ { "http://a/b/c/d;p?q", "g", "http://a/b/c/g" },
+ { "http://a/b/c/d;p?q", "./g", "http://a/b/c/g" },
+ { "http://a/b/c/d;p?q", "g/", "http://a/b/c/g/" },
+ { "http://a/b/c/d;p?q", "/g", "http://a/g" },
+ { "http://a/b/c/d;p?q", "//g", "http://g" },
+ { "http://a/b/c/d;p?q", "?y", "http://a/b/c/d;p?y" },
+ { "http://a/b/c/d;p?q", "g?y", "http://a/b/c/g?y" },
+ { "http://a/b/c/d;p?q", "#s", "http://a/b/c/d;p?q#s" },
+ { "http://a/b/c/d;p?q", "g#s", "http://a/b/c/g#s" },
+ { "http://a/b/c/d;p?q", "g?y#s", "http://a/b/c/g?y#s" },
+ { "http://a/b/c/d;p?q", ";x", "http://a/b/c/;x" },
+ { "http://a/b/c/d;p?q", "g;x", "http://a/b/c/g;x" },
+ { "http://a/b/c/d;p?q", "g;x?y#s", "http://a/b/c/g;x?y#s" },
+ { "http://a/b/c/d;p?q", "", "http://a/b/c/d;p?q" },
+ { "http://a/b/c/d;p?q", ".", "http://a/b/c/" },
+ { "http://a/b/c/d;p?q", "./", "http://a/b/c/" },
+ { "http://a/b/c/d;p?q", "..", "http://a/b/" },
+ { "http://a/b/c/d;p?q", "../", "http://a/b/" },
+ { "http://a/b/c/d;p?q", "../g", "http://a/b/g" },
+ { "http://a/b/c/d;p?q", "../..", "http://a/" },
+ { "http://a/b/c/d;p?q", "../../", "http://a/" },
+ { "http://a/b/c/d;p?q", "../../g", "http://a/g" },
+ { "http://a/b/c/d;p?q", "../../../g", "http://a/g" },
+ { "http://a/b/c/d;p?q", "../../../../g", "http://a/g" },
+ { "http://a/b/c/d;p?q", "/./g", "http://a/g" },
+ { "http://a/b/c/d;p?q", "/../g", "http://a/g" },
+ { "http://a/b/c/d;p?q", "g.", "http://a/b/c/g." },
+ { "http://a/b/c/d;p?q", ".g", "http://a/b/c/.g" },
+ { "http://a/b/c/d;p?q", "g..", "http://a/b/c/g.." },
+ { "http://a/b/c/d;p?q", "..g", "http://a/b/c/..g" },
+ { "http://a/b/c/d;p?q", "./../g", "http://a/b/g" },
+ { "http://a/b/c/d;p?q", "./g/.", "http://a/b/c/g/" },
+ { "http://a/b/c/d;p?q", "g/./h", "http://a/b/c/g/h" },
+ { "http://a/b/c/d;p?q", "g/../h", "http://a/b/c/h" },
+ { "http://a/b/c/d;p?q", "g;x=1/./y", "http://a/b/c/g;x=1/y" },
+ { "http://a/b/c/d;p?q", "g;x=1/../y", "http://a/b/c/y" },
+ { "http://a/b/c/d;p?q", "g?y/./x", "http://a/b/c/g?y/./x" },
+ { "http://a/b/c/d;p?q", "g?y/../x", "http://a/b/c/g?y/../x" },
+ { "http://a/b/c/d;p?q", "g#s/./x", "http://a/b/c/g#s/./x" },
+ { "http://a/b/c/d;p?q", "g#s/../x", "http://a/b/c/g#s/../x" },
+ { "http://a/b/c/d;p?q", "http:g", "http:g" },
+
+ { "http!://a/b/c/d;p?q", "g:h", "g:h" },
+ { "http!://a/b/c/d;p?q", "g", nullptr },
+ { "http:b/c/d;p?q", "g:h", "g:h" },
+ { "http:b/c/d;p?q", "g", "http:b/c/g" },
+ { "http://a/b/../", "../c", "http://a/c" },
+ { "http://a/b/..", "../c", "http://a/c" },
+ { "http://a/./b/", ".././.././../c", "http://a/c" },
+ { "http://a", "b", "http://a/b" },
+ { "", "http://a/b/../c", "http://a/c" },
+
+ { "http://a/b/c", "d", "http://a/b/d" },
+ { "http://a/b/c/", "d", "http://a/b/c/d" },
+ { "http://a/b/c//", "d", "http://a/b/c//d" } };
+
+ for (std::size_t i = 0; i < SAL_N_ELEMENTS(aRelToAbsTest); ++i)
+ {
+ OUString aAbs;
+ bool bMalformed = false;
+ try {
+ aAbs = rtl::Uri::convertRelToAbs(
+ OUString::createFromAscii(aRelToAbsTest[i].pBase),
+ OUString::createFromAscii(aRelToAbsTest[i].pRel));
+ } catch (const rtl::MalformedUriException &) {
+ bMalformed = true;
+ }
+ if (bMalformed
+ ? aRelToAbsTest[i].pAbs != nullptr
+ : (aRelToAbsTest[i].pAbs == nullptr
+ || !aAbs.equalsAscii(aRelToAbsTest[i].pAbs)))
+ {
+ printf(
+ "FAILED convertRelToAbs(%s, %s) -> %s != %s\n",
+ aRelToAbsTest[i].pBase, aRelToAbsTest[i].pRel,
+ (bMalformed
+ ? "<MALFORMED>"
+ : OUStringToOString(
+ aAbs, RTL_TEXTENCODING_UTF8).getStr()),
+ (aRelToAbsTest[i].pAbs == nullptr
+ ? "<MALFORMED>" : aRelToAbsTest[i].pAbs));
+ CPPUNIT_ASSERT(false);
+ }
+ }
+
+ // Check encode with unusual text encodings:
+
+ {
+ static constexpr OUStringLiteral aText1U = u" !\u0401\u045F";
+ aText1 = OUString(aText1U);
+ aText2 = "%20!%A1%FF";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 20",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_ISO_8859_5));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 20a",
+ aText1,
+ rtl::Uri::decode(
+ aText2, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ISO_8859_5));
+ }
+ {
+ static constexpr OUStringLiteral aText1U = u" !\u0401\u0700\u045F";
+ aText1 = OUString(aText1U);
+ static constexpr OUStringLiteral aText2U =
+ u"%20!%A1\u0700%FF";
+ aText2 = OUString(aText2U);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 21",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_ISO_8859_5));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 21a",
+ aText1,
+ rtl::Uri::decode(
+ aText2, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ISO_8859_5));
+ }
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ {
+ static constexpr OUStringLiteral aText1U = u" !\u028A\U00022513";
+ aText1 = OUString(aText1U);
+ aText2 = "%20!%81%30%B1%33%95%39%C5%37";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 22",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_GB_18030));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 22a",
+ aText1,
+ rtl::Uri::decode(
+ aText2, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_GB_18030));
+ }
+#endif
+ // Check strict mode:
+
+ {
+ static constexpr OUStringLiteral aText1U = u" !\u0401\u0700\u045F";
+ aText1 = OUString(aText1U);
+ aText2 = OUString();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 23",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeStrict,
+ RTL_TEXTENCODING_ISO_8859_5));
+ }
+ {
+ aText1 = "%20%C4%80%FF";
+ aText2 = OUString();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 24",
+ aText2,
+ rtl::Uri::decode(
+ aText1, rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8));
+ }
+#if WITH_LOCALE_ALL || WITH_LOCALE_zh
+ {
+ aText1 = "%81 ";
+ aText2 = OUString();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 25",
+ aText2,
+ rtl::Uri::decode(
+ aText1, rtl_UriDecodeStrict, RTL_TEXTENCODING_GB_18030));
+ }
+ {
+ aText1 = "%81%20";
+ aText2 = OUString();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 26",
+ aText2,
+ rtl::Uri::decode(
+ aText1, rtl_UriDecodeStrict, RTL_TEXTENCODING_GB_18030));
+ }
+ {
+ aText1 = "%81%30%B1%33";
+ static constexpr OUStringLiteral aText2U = u"\u028A";
+ aText2 = OUString(aText2U);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 27",
+ aText2,
+ rtl::Uri::decode(
+ aText1, rtl_UriDecodeStrict, RTL_TEXTENCODING_GB_18030));
+ }
+ {
+ aText1 = "%810%B13";
+ static constexpr OUStringLiteral aText2U = u"\u028A";
+ aText2 = OUString(aText2U);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 28",
+ aText2,
+ rtl::Uri::decode(
+ aText1, rtl_UriDecodeStrict, RTL_TEXTENCODING_GB_18030));
+ }
+#endif
+ // Check rtl_UriEncodeStrictKeepEscapes mode:
+
+ {
+ aText1 = "%%ea%c3%aa";
+ aText2 = "%25%EA%C3%AA";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 29",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeStrictKeepEscapes,
+ RTL_TEXTENCODING_UTF8));
+ }
+ {
+ static constexpr OUStringLiteral aText1U = u"\u00EA";
+ aText1 = OUString(aText1U);
+ aText2 = "%C3%AA";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 30",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeStrictKeepEscapes,
+ RTL_TEXTENCODING_UTF8));
+ }
+ {
+ static constexpr OUStringLiteral aText1U = u" !\u0401\u0700\u045F";
+ aText1 = OUString(aText1U);
+ aText2 = OUString();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "failure 23",
+ aText2,
+ rtl::Uri::encode(
+ aText1, rtl_UriCharClassUric, rtl_UriEncodeStrictKeepEscapes,
+ RTL_TEXTENCODING_ISO_8859_5));
+ }
+}
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/qa/rtl/uuid/rtl_Uuid.cxx b/sal/qa/rtl/uuid/rtl_Uuid.cxx
new file mode 100644
index 000000000..aae77cfe3
--- /dev/null
+++ b/sal/qa/rtl/uuid/rtl_Uuid.cxx
@@ -0,0 +1,159 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rtl/uuid.h>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#ifdef _WIN32
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#elif defined UNX
+#include <unistd.h>
+#include <time.h>
+#endif
+
+
+namespace rtl_Uuid
+{
+class createUuid : public CppUnit::TestFixture
+{
+public:
+#define TEST_UUID 20
+ void createUuid_001()
+ {
+ sal_uInt8 aNode[TEST_UUID][16];
+ sal_Int32 i,i2;
+ for( i = 0 ; i < TEST_UUID ; i ++ )
+ {
+ rtl_createUuid( aNode[i], nullptr, false );
+ }
+ bool bRes = true;
+ for( i = 0 ; i < TEST_UUID ; i ++ )
+ {
+ for( i2 = i+1 ; i2 < TEST_UUID ; i2 ++ )
+ {
+ if ( rtl_compareUuid( aNode[i] , aNode[i2] ) == 0 )
+ {
+ bRes = false;
+ break;
+ }
+ }
+ if ( !bRes )
+ break;
+ }
+ CPPUNIT_ASSERT_MESSAGE("createUuid: every uuid must be different.", bRes);
+ }
+ /*
+ void createUuid_002()
+ {
+ sal_uInt8 pNode[16];
+ sal_uInt8 aNode[TEST_UUID][16];
+ sal_Int32 i,i2;
+ for( i = 0 ; i < TEST_UUID ; i ++ )
+ {
+ rtl_createUuid( aNode[i], pNode, sal_True );
+ }
+ sal_Bool bRes = sal_True;
+ for( i = 0 ; i < TEST_UUID ; i ++ )
+ {
+ //printUuid( aNode[i] );
+ for( i2 = i+1 ; i2 < TEST_UUID ; i2 ++ )
+ {
+ if ( rtl_compareUuid( aNode[i] , aNode[i2] ) == 0 )
+ {
+ bRes = sal_False;
+ break;
+ }
+ }
+ if ( bRes == sal_False )
+ break;
+ }
+ CPPUNIT_ASSERT_MESSAGE("createUuid: every uuid must be different.", bRes == sal_True );
+ }*/
+
+ CPPUNIT_TEST_SUITE(createUuid);
+ CPPUNIT_TEST(createUuid_001);
+ //CPPUNIT_TEST(createUuid_002);
+ CPPUNIT_TEST_SUITE_END();
+}; // class createUuid
+
+class createNamedUuid : public CppUnit::TestFixture
+{
+public:
+ void createNamedUuid_001()
+ {
+ sal_uInt8 NameSpace_DNS[16] = RTL_UUID_NAMESPACE_DNS;
+ sal_uInt8 NameSpace_URL[16] = RTL_UUID_NAMESPACE_URL;
+ sal_uInt8 pPriorCalculatedUUID[16] = {
+ 0x52,0xc9,0x30,0xa5,
+ 0xd1,0x61,0x3b,0x16,
+ 0x98,0xc5,0xf8,0xd1,
+ 0x10,0x10,0x6d,0x4d };
+
+ sal_uInt8 pNamedUUID[16], pNamedUUID2[16];
+
+ // Same name does generate the same uuid
+ rtl_String *pName = nullptr;
+ rtl_string_newFromStr( &pName , "this is a bla.blubs.DNS-Name" );
+ rtl_createNamedUuid( pNamedUUID , NameSpace_DNS , pName );
+ rtl_createNamedUuid( pNamedUUID2 , NameSpace_DNS , pName );
+ CPPUNIT_ASSERT_MESSAGE( "Same name should generate the same uuid", ! memcmp( pNamedUUID , pNamedUUID2 , 16 ));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Same name should generate the same uuid", sal_Int32(0), rtl_compareUuid( pNamedUUID , pNamedUUID2 ) );
+ CPPUNIT_ASSERT_MESSAGE( "Same name should generate the same uuid", ! memcmp( pNamedUUID , pPriorCalculatedUUID , 16 ) );
+
+ // Different names does not generate the same uuid
+ rtl_string_newFromStr( &pName , "this is a bla.blubs.DNS-Namf" );
+ rtl_createNamedUuid( pNamedUUID2 , NameSpace_DNS , pName );
+ CPPUNIT_ASSERT_MESSAGE("Different names does not generate the same uuid.", memcmp( pNamedUUID , pNamedUUID2 , 16 ) );
+
+ // the same name with different namespace uuid produces different uuids
+ rtl_createNamedUuid( pNamedUUID , NameSpace_URL , pName );
+ CPPUNIT_ASSERT_MESSAGE( " same name with different namespace uuid produces different uuids", memcmp( pNamedUUID , pNamedUUID2 , 16 ));
+ CPPUNIT_ASSERT_MESSAGE( " same name with different namespace uuid produces different uuids", rtl_compareUuid( pNamedUUID , pNamedUUID2 ) != 0);
+
+ //test compareUuid
+ if ( rtl_compareUuid( pNamedUUID , pNamedUUID2 ) > 0 )
+ { CPPUNIT_ASSERT_MESSAGE( " compare uuids", rtl_compareUuid( pNamedUUID2 , pNamedUUID ) < 0);
+ }
+ else
+ CPPUNIT_ASSERT_MESSAGE( " compare uuids", rtl_compareUuid( pNamedUUID2 , pNamedUUID ) > 0);
+
+ rtl_string_release( pName );
+ }
+
+ CPPUNIT_TEST_SUITE(createNamedUuid);
+ CPPUNIT_TEST(createNamedUuid_001);
+ CPPUNIT_TEST_SUITE_END();
+}; // class createNamedUuid
+
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_Uuid::createUuid);
+CPPUNIT_TEST_SUITE_REGISTRATION(rtl_Uuid::createNamedUuid);
+} // namespace rtl_Uuid
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */