1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_sal.hxx"
31 // autogenerated file with codegen.pl
32 
33 #include <math.h>
34 #include <stdio.h>
35 
36 #include <algorithm> // STL
37 
38 #include <testshl/simpleheader.hxx>
39 #include "stringhelper.hxx"
40 #include "valueequal.hxx"
41 
42 inline void printOUString( ::rtl::OUString const & _suStr )
43 {
44     rtl::OString aString;
45 
46     t_print( "OUString: " );
47     aString = ::rtl::OUStringToOString( _suStr, RTL_TEXTENCODING_ASCII_US );
48     t_print( "'%s'\n", aString.getStr( ) );
49 }
50 
51 namespace rtl_OUString
52 {
53 
54     class ctors_rtl_uString : public CppUnit::TestFixture
55     {
56 
57     public:
58         /// test of OUString(rtl_uString*)
59         void ctors_001()
60             {
61                 rtl::OUString *pStr = new rtl::OUString( rtl::OUString::createFromAscii("a String") );
62 
63                 rtl::OUString aStrToTest(pStr->pData);
64                 delete pStr;
65 
66                 // maybe here should we do something with current memory
67                 char* pBuffer = (char*) malloc(2 * 8);
68                 memset(pBuffer, 0, 2 * 8);
69                 free(pBuffer);
70 
71                 sal_Bool bResult = aStrToTest.equals(rtl::OUString::createFromAscii("a String"));
72                 CPPUNIT_ASSERT_MESSAGE("String must not be empty",  bResult == sal_True);
73             }
74 
75         // Change the following lines only, if you add, remove or rename
76         // member functions of the current class,
77         // because these macros are need by auto register mechanism.
78 
79         CPPUNIT_TEST_SUITE(ctors_rtl_uString);
80         CPPUNIT_TEST(ctors_001);
81         CPPUNIT_TEST_SUITE_END();
82     };
83 
84 // -----------------------------------------------------------------------------
85 class valueOf : public CppUnit::TestFixture
86 {
87     void valueOf_float_test_impl(float _nValue)
88         {
89             rtl::OUString suValue;
90             suValue = rtl::OUString::valueOf( _nValue );
91             rtl::OString sValue;
92             sValue <<= suValue;
93             t_print(T_VERBOSE, "nFloat := %.9f  sValue := %s\n", _nValue, sValue.getStr());
94 
95             float nValueATOF = static_cast<float>(atof( sValue.getStr() ));
96 
97             bool bEqualResult = is_float_equal(_nValue, nValueATOF);
98             CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
99         }
100 
101     void valueOf_float_test(float _nValue)
102         {
103             valueOf_float_test_impl(_nValue);
104 
105             // test also the negative part.
106             float nNegativeValue = -_nValue;
107             valueOf_float_test_impl(nNegativeValue);
108         }
109 
110 public:
111     // insert your test code here.
112     void valueOf_float_test_001()
113     {
114         // this is demonstration code
115         // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1);
116         float nValue = 3.0f;
117         valueOf_float_test(nValue);
118     }
119 
120     void valueOf_float_test_002()
121     {
122         float nValue = 3.5f;
123         valueOf_float_test(nValue);
124     }
125 
126     void valueOf_float_test_003()
127     {
128         float nValue = 3.0625f;
129         valueOf_float_test(nValue);
130     }
131 
132     void valueOf_float_test_004()
133     {
134         float nValue = 3.502525f;
135         valueOf_float_test(nValue);
136     }
137 
138     void valueOf_float_test_005()
139     {
140         float nValue = 3.141592f;
141         valueOf_float_test(nValue);
142     }
143 
144     void valueOf_float_test_006()
145     {
146         float nValue = 3.5025255f;
147         valueOf_float_test(nValue);
148     }
149 
150     void valueOf_float_test_007()
151     {
152         float nValue = 3.0039062f;
153         valueOf_float_test(nValue);
154     }
155 
156 private:
157 
158     void valueOf_double_test_impl(double _nValue)
159         {
160             rtl::OUString suValue;
161             suValue = rtl::OUString::valueOf( _nValue );
162             rtl::OString sValue;
163             sValue <<= suValue;
164             t_print(T_VERBOSE, "nDouble := %.20f  sValue := %s\n", _nValue, sValue.getStr());
165 
166             double nValueATOF = atof( sValue.getStr() );
167 
168             bool bEqualResult = is_double_equal(_nValue, nValueATOF);
169             CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
170         }
171 
172     void valueOf_double_test(double _nValue)
173         {
174             valueOf_double_test_impl(_nValue);
175 
176             // test also the negative part.
177             double nNegativeValue = -_nValue;
178             valueOf_double_test_impl(nNegativeValue);
179         }
180 public:
181 
182     // valueOf double
183     void valueOf_double_test_001()
184         {
185             double nValue = 3.0;
186             valueOf_double_test(nValue);
187         }
188     void valueOf_double_test_002()
189         {
190             double nValue = 3.5;
191             valueOf_double_test(nValue);
192         }
193     void valueOf_double_test_003()
194         {
195             double nValue = 3.0625;
196             valueOf_double_test(nValue);
197         }
198     void valueOf_double_test_004()
199         {
200             double nValue = 3.1415926535;
201             valueOf_double_test(nValue);
202         }
203     void valueOf_double_test_005()
204         {
205             double nValue = 3.141592653589793;
206             valueOf_double_test(nValue);
207         }
208     void valueOf_double_test_006()
209         {
210             double nValue = 3.1415926535897932;
211             valueOf_double_test(nValue);
212         }
213     void valueOf_double_test_007()
214         {
215             double nValue = 3.14159265358979323;
216             valueOf_double_test(nValue);
217         }
218     void valueOf_double_test_008()
219         {
220             double nValue = 3.141592653589793238462643;
221             valueOf_double_test(nValue);
222         }
223 
224 
225     // Change the following lines only, if you add, remove or rename
226     // member functions of the current class,
227     // because these macros are need by auto register mechanism.
228 
229     CPPUNIT_TEST_SUITE(valueOf);
230     CPPUNIT_TEST(valueOf_float_test_001);
231     CPPUNIT_TEST(valueOf_float_test_002);
232     CPPUNIT_TEST(valueOf_float_test_003);
233     CPPUNIT_TEST(valueOf_float_test_004);
234     CPPUNIT_TEST(valueOf_float_test_005);
235     CPPUNIT_TEST(valueOf_float_test_006);
236     CPPUNIT_TEST(valueOf_float_test_007);
237 
238     CPPUNIT_TEST(valueOf_double_test_001);
239     CPPUNIT_TEST(valueOf_double_test_002);
240     CPPUNIT_TEST(valueOf_double_test_003);
241     CPPUNIT_TEST(valueOf_double_test_004);
242     CPPUNIT_TEST(valueOf_double_test_005);
243     CPPUNIT_TEST(valueOf_double_test_006);
244     CPPUNIT_TEST(valueOf_double_test_007);
245     CPPUNIT_TEST(valueOf_double_test_008);
246     CPPUNIT_TEST_SUITE_END();
247 }; // class valueOf
248 
249 //------------------------------------------------------------------------
250 // testing the method toDouble()
251 //------------------------------------------------------------------------
252 template<class T>
253 sal_Int16 SAL_CALL checkPrecisionSize()
254 {
255 	// sal_Int16 nSize = sizeof(T);
256 	volatile T nCalcValue = 1.0;
257 
258 
259 	// (i + 1) is the current precision
260     // numerical series
261     // 1.1
262     // 10.1
263     // 100.1
264     // ...
265     // 1000...0.1
266 
267 	sal_Int16 i = 0;
268 	for (i=0;i<50;i++)
269 	{
270 		nCalcValue *= 10;
271 		volatile T nValue = nCalcValue + static_cast<T>(0.1);
272 		volatile T dSub = nValue - nCalcValue;
273 		// ----- 0.11 ---- 0.1 ---- 0.09 -----
274 		if (0.11 > dSub && dSub < 0.09)
275 		{
276 			// due to the fact, that the value is break down we sub 1 from the precision value
277 			// but to suppress this, we start at zero, precision is i+1 till here --i;
278 			break;
279 		}
280 	}
281 
282 	sal_Int16 j= 0;
283 	nCalcValue = 1.0;
284 
285     // numerical series
286     // 1.1
287     // 1.01
288     // 1.001
289     // ...
290     // 1.000...001
291 
292 	for (j=0;j<50;j++)
293 	{
294 		nCalcValue /= 10;
295 		volatile T nValue = nCalcValue + static_cast<T>(1.0);
296 		volatile T dSub = nValue - static_cast<T>(1.0);
297 		// ---- 0.02 ----- 0.01 ---- 0 --- -0.99 ---- -0.98 ----
298 		// volatile T dSubAbsolut = fabs(dSub);
299 		// ---- 0.02 ----- 0.01 ---- 0 (cut)
300 		if ( dSub == 0)
301 			break;
302 	}
303 	if (i != j)
304 	{
305             // hmmm....
306             // imho i +- 1 == j is a good value
307             int n = i - j;
308             if (n < 0) n = -n;
309             if (n <= 1)
310             {
311                 return std::min(i,j);
312             }
313             else
314             {
315                 t_print("warning: presision differs more than 1!\n");
316             }
317         }
318 
319 	return i;
320 }
321 
322 // -----------------------------------------------------------------------------
323 
324     class testPrecision
325     {
326     public:
327         testPrecision()
328             {
329                 sal_Int16 nPrecision;
330                 nPrecision = checkPrecisionSize<float>();
331                 t_print("precision of float: %d sizeof()=%d \n", nPrecision, sizeof(float));
332 
333                 nPrecision = checkPrecisionSize<double>();
334                 t_print("precision of double: %d sizeof()=%d \n", nPrecision, sizeof(double));
335 
336                 nPrecision = checkPrecisionSize<long double>();
337                 t_print("precision of long double: %d sizeof()=%d \n", nPrecision, sizeof(long double));
338 
339             }
340 
341     };
342 
343     class toInt: public CppUnit::TestFixture {
344     public:
345         void test() {
346             CPPUNIT_ASSERT_EQUAL(
347                 static_cast< sal_Int32 >(-0x76543210),
348                 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-76543210")).
349                  toInt32(16)));
350             CPPUNIT_ASSERT_EQUAL(
351                 static_cast< sal_Int32 >(0xFEDCBA98),
352                 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("+FEDCBA98")).
353                  toInt32(16)));
354             CPPUNIT_ASSERT_EQUAL(
355                 static_cast< sal_Int64 >(-SAL_CONST_INT64(0x76543210FEDCBA98)),
356                 (rtl::OUString(
357                     RTL_CONSTASCII_USTRINGPARAM("-76543210FEDCBA98")).
358                  toInt64(16)));
359             CPPUNIT_ASSERT_EQUAL(
360                 static_cast< sal_Int64 >(SAL_CONST_INT64(0xFEDCBA9876543210)),
361                 (rtl::OUString(
362                     RTL_CONSTASCII_USTRINGPARAM("+FEDCBA9876543210")).
363                  toInt64(16)));
364         }
365 
366         CPPUNIT_TEST_SUITE(toInt);
367         CPPUNIT_TEST(test);
368         CPPUNIT_TEST_SUITE_END();
369     };
370 
371 // -----------------------------------------------------------------------------
372 // - toDouble (tests)
373 // -----------------------------------------------------------------------------
374     class toDouble : public CppUnit::TestFixture
375     {
376     public:
377         void toDouble_test_impl(rtl::OString const& _sValue)
378             {
379             	//t_print("the original str is %s\n", _sValue.getStr());
380                 double nValueATOF = atof( _sValue.getStr() );
381 		//t_print("original data is %e\n", nValueATOF);
382                 rtl::OUString suValue = rtl::OUString::createFromAscii( _sValue.getStr() );
383                 double nValueToDouble = suValue.toDouble();
384                 //t_print("result data is %e\n", nValueToDouble);
385 
386                 bool bEqualResult = is_double_equal(nValueToDouble, nValueATOF);
387                 CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
388             }
389 
390         void toDouble_test(rtl::OString const& _sValue)
391             {
392                 toDouble_test_impl(_sValue);
393 
394                 // test also the negativ part.
395                 rtl::OString sNegativValue("-");
396                 sNegativValue += _sValue;
397                 toDouble_test_impl(sNegativValue);
398             }
399 
400         // insert your test code here.
401         void toDouble_selftest()
402             {
403                 t_print("Start selftest:\n");
404                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.01) == false);
405                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.001) == false);
406                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.0001) == false);
407                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.00001) == false);
408                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.000001) == false);
409                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000001) == false);
410                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000001) == false);
411                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000001) == false);
412                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000001) == false);
413                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000000001) == false);
414                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000000001) == false);
415                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000000001) == false);
416                 // we check til 15 values after comma
417                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.00000000000001) == true);
418                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.000000000000001) == true);
419                 CPPUNIT_ASSERT (is_double_equal(1.0, 1.0000000000000001) == true);
420                 t_print("Selftest done.\n");
421             }
422 
423         void toDouble_test_3()
424             {
425                 rtl::OString sValue("3");
426                 toDouble_test(sValue);
427             }
428         void toDouble_test_3_5()
429             {
430                 rtl::OString sValue("3.5");
431                 toDouble_test(sValue);
432             }
433         void toDouble_test_3_0625()
434             {
435                 rtl::OString sValue("3.0625");
436                 toDouble_test(sValue);
437             }
438         void toDouble_test_pi()
439             {
440                 // value from http://www.angio.net/pi/digits/50.txt
441                 rtl::OString sValue("3.141592653589793238462643383279502884197169399375");
442                 toDouble_test(sValue);
443             }
444 
445         void toDouble_test_1()
446             {
447                 rtl::OString sValue("1");
448                 toDouble_test(sValue);
449             }
450         void toDouble_test_10()
451             {
452                 rtl::OString sValue("10");
453                 toDouble_test(sValue);
454             }
455         void toDouble_test_100()
456             {
457                 rtl::OString sValue("100");
458                 toDouble_test(sValue);
459             }
460         void toDouble_test_1000()
461             {
462                 rtl::OString sValue("1000");
463                 toDouble_test(sValue);
464             }
465         void toDouble_test_10000()
466             {
467                 rtl::OString sValue("10000");
468                 toDouble_test(sValue);
469             }
470         void toDouble_test_1e99()
471             {
472                 rtl::OString sValue("1e99");
473                 toDouble_test(sValue);
474             }
475         void toDouble_test_1e_n99()
476             {
477                 rtl::OString sValue("1e-99");
478                 toDouble_test(sValue);
479             }
480         void toDouble_test_1e308()
481             {
482                 rtl::OString sValue("1e308");
483                 toDouble_test(sValue);
484             }
485 
486         // Change the following lines only, if you add, remove or rename
487         // member functions of the current class,
488         // because these macros are need by auto register mechanism.
489 
490         CPPUNIT_TEST_SUITE(toDouble);
491         CPPUNIT_TEST(toDouble_selftest);
492 
493         CPPUNIT_TEST(toDouble_test_3);
494         CPPUNIT_TEST(toDouble_test_3_5);
495         CPPUNIT_TEST(toDouble_test_3_0625);
496         CPPUNIT_TEST(toDouble_test_pi);
497         CPPUNIT_TEST(toDouble_test_1);
498         CPPUNIT_TEST(toDouble_test_10);
499         CPPUNIT_TEST(toDouble_test_100);
500         CPPUNIT_TEST(toDouble_test_1000);
501         CPPUNIT_TEST(toDouble_test_10000);
502         CPPUNIT_TEST(toDouble_test_1e99);
503         CPPUNIT_TEST(toDouble_test_1e_n99);
504         CPPUNIT_TEST(toDouble_test_1e308);
505         CPPUNIT_TEST_SUITE_END();
506     }; // class toDouble
507 
508 // -----------------------------------------------------------------------------
509 // - toFloat (tests)
510 // -----------------------------------------------------------------------------
511     class toFloat : public CppUnit::TestFixture
512     {
513     public:
514         void toFloat_test_impl(rtl::OString const& _sValue)
515             {
516             	//t_print("the original str is %s\n", _sValue.getStr());
517                 float nValueATOF = static_cast<float>(atof( _sValue.getStr() ));
518 		//t_print("the original str is %.10f\n", nValueATOF);
519                 rtl::OUString suValue = rtl::OUString::createFromAscii( _sValue.getStr() );
520                 float nValueToFloat = suValue.toFloat();
521                 //t_print("the result str is %.10f\n", nValueToFloat);
522 
523                 bool bEqualResult = is_float_equal(nValueToFloat, nValueATOF);
524                 CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
525             }
526 
527         void toFloat_test(rtl::OString const& _sValue)
528             {
529                 toFloat_test_impl(_sValue);
530 
531                 // test also the negativ part.
532                 rtl::OString sNegativValue("-");
533                 sNegativValue += _sValue;
534                 toFloat_test_impl(sNegativValue);
535             }
536 
537         // insert your test code here.
538         void toFloat_selftest()
539             {
540                 t_print("Start selftest:\n");
541                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.01f) == false);
542                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.001f) == false);
543                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.0001f) == false);
544                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.00001f) == false);
545                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.000002f) == false);
546                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.0000001f) == true);
547                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.00000001f) == true);
548                 CPPUNIT_ASSERT (is_float_equal(1.0f, 1.000000001f) == true);
549 
550                 t_print("Selftest done.\n");
551             }
552 
553         void toFloat_test_3()
554             {
555                 rtl::OString sValue("3");
556                 toFloat_test(sValue);
557             }
558         void toFloat_test_3_5()
559             {
560                 rtl::OString sValue("3.5");
561                 toFloat_test(sValue);
562             }
563         void toFloat_test_3_0625()
564             {
565                 rtl::OString sValue("3.0625");
566                 toFloat_test(sValue);
567             }
568         void toFloat_test_3_0625_e()
569             {
570                 rtl::OString sValue("3.0625e-4");
571                 toFloat_test(sValue);
572             }
573         void toFloat_test_pi()
574             {
575                 // value from http://www.angio.net/pi/digits/50.txt
576                 rtl::OString sValue("3.141592653589793238462643383279502884197169399375");
577                 toFloat_test(sValue);
578             }
579 
580         void toFloat_test_1()
581             {
582                 rtl::OString sValue("1");
583                 toFloat_test(sValue);
584             }
585         void toFloat_test_10()
586             {
587                 rtl::OString sValue("10");
588                 toFloat_test(sValue);
589             }
590         void toFloat_test_100()
591             {
592                 rtl::OString sValue("100");
593                 toFloat_test(sValue);
594             }
595         void toFloat_test_1000()
596             {
597                 rtl::OString sValue("1000");
598                 toFloat_test(sValue);
599             }
600         void toFloat_test_10000()
601             {
602                 rtl::OString sValue("10000");
603                 toFloat_test(sValue);
604             }
605         void toFloat_test_mix()
606             {
607                 rtl::OString sValue("456789321455.123456789012");
608                 toFloat_test(sValue);
609             }
610         void toFloat_test_1e99()
611             {
612                 rtl::OString sValue("1e99");
613                 toFloat_test(sValue);
614             }
615         void toFloat_test_1e_n99()
616             {
617                 rtl::OString sValue("1e-9");
618                 toFloat_test(sValue);
619             }
620         void toFloat_test_1e308()
621             {
622                 rtl::OString sValue("1e308");
623                 toFloat_test(sValue);
624             }
625 
626         // Change the following lines only, if you add, remove or rename
627         // member functions of the current class,
628         // because these macros are need by auto register mechanism.
629 
630         CPPUNIT_TEST_SUITE(toFloat);
631         CPPUNIT_TEST(toFloat_selftest);
632 
633         CPPUNIT_TEST(toFloat_test_3);
634         CPPUNIT_TEST(toFloat_test_3_5);
635         CPPUNIT_TEST(toFloat_test_3_0625);
636         CPPUNIT_TEST(toFloat_test_3_0625_e);
637         CPPUNIT_TEST(toFloat_test_pi);
638         CPPUNIT_TEST(toFloat_test_1);
639         CPPUNIT_TEST(toFloat_test_10);
640         CPPUNIT_TEST(toFloat_test_100);
641         CPPUNIT_TEST(toFloat_test_1000);
642         CPPUNIT_TEST(toFloat_test_10000);
643         CPPUNIT_TEST(toFloat_test_mix);
644         CPPUNIT_TEST(toFloat_test_1e99);
645         CPPUNIT_TEST(toFloat_test_1e_n99);
646         CPPUNIT_TEST(toFloat_test_1e308);
647         CPPUNIT_TEST_SUITE_END();
648     }; // class toFloat
649 
650 // -----------------------------------------------------------------------------
651 // - lastIndexOf (tests)
652 // -----------------------------------------------------------------------------
653 class lastIndexOf : public CppUnit::TestFixture
654 {
655 
656 public:
657     void lastIndexOf_oustring(rtl::OUString const& _suStr, rtl::OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos)
658         {
659             // Algorithm
660             // search the string _suSearchStr (rtl::OUString) in the string _suStr.
661             // check if the _nExpectedResultPos occurs.
662 
663             sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr);
664             CPPUNIT_ASSERT_MESSAGE("expected position is wrong", nPos == _nExpectedResultPos);
665         }
666 
667     void lastIndexOf_salunicode(rtl::OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos)
668         {
669             // Algorithm
670             // search the unicode char _suSearchChar (sal_Unicode) in the string _suStr.
671             // check if the _nExpectedResultPos occurs.
672 
673             sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar);
674             CPPUNIT_ASSERT_MESSAGE("expected position is wrong", nPos == _nExpectedResultPos);
675         }
676 
677     void lastIndexOf_oustring_offset(rtl::OUString const& _suStr, rtl::OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset)
678         {
679             sal_Int32 nPos = _suStr.lastIndexOf(_suSearchStr, _nStartOffset);
680             CPPUNIT_ASSERT_MESSAGE("expected position is wrong", nPos == _nExpectedResultPos);
681         }
682 
683     void lastIndexOf_salunicode_offset(rtl::OUString const& _suStr, sal_Unicode _cuSearchChar, sal_Int32 _nExpectedResultPos, sal_Int32 _nStartOffset)
684         {
685             sal_Int32 nPos = _suStr.lastIndexOf(_cuSearchChar, _nStartOffset);
686             CPPUNIT_ASSERT_MESSAGE("expected position is wrong", nPos == _nExpectedResultPos);
687         }
688 
689     // -----------------------------------------------------------------------------
690 
691     void lastIndexOf_test_oustring_offset_001()
692         {
693             // search for sun, start at the end, found (pos==0)
694             rtl::OUString aStr = rtl::OUString::createFromAscii("sun java system");
695             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
696             lastIndexOf_oustring_offset(aStr, aSearchStr, 0, aStr.getLength());
697         }
698 
699     void lastIndexOf_test_oustring_offset_002()
700         {
701             // search for sun, start at pos = 3, found (pos==0)
702             rtl::OUString aStr = rtl::OUString::createFromAscii("sun java system");
703             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
704             lastIndexOf_oustring_offset(aStr, aSearchStr, 0, 3);
705         }
706 
707     void lastIndexOf_test_oustring_offset_003()
708         {
709             // search for sun, start at pos = 2, found (pos==-1)
710             rtl::OUString aStr = rtl::OUString::createFromAscii("sun java system");
711             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
712             lastIndexOf_oustring_offset(aStr, aSearchStr, -1, 2);
713         }
714 
715     void lastIndexOf_test_oustring_offset_004()
716         {
717             // search for sun, start at the end, found (pos==0)
718             rtl::OUString aStr = rtl::OUString::createFromAscii("sun java system");
719             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
720             lastIndexOf_oustring_offset(aStr, aSearchStr, -1, -1);
721         }
722 
723     void lastIndexOf_test_oustring_001()
724         {
725             // search for sun, found (pos==0)
726             rtl::OUString aStr = rtl::OUString::createFromAscii("sun java system");
727             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
728             lastIndexOf_oustring(aStr, aSearchStr, 0);
729         }
730 
731     void lastIndexOf_test_oustring_002()
732         {
733             // search for sun, found (pos==4)
734             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun java system");
735             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
736             lastIndexOf_oustring(aStr, aSearchStr, 4);
737         }
738 
739     void lastIndexOf_test_oustring_003()
740         {
741             // search for sun, found (pos==8)
742             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun sun java system");
743             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
744             lastIndexOf_oustring(aStr, aSearchStr, 8);
745         }
746 
747     void lastIndexOf_test_oustring_004()
748         {
749             // search for sun, found (pos==8)
750             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun sun");
751             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
752             lastIndexOf_oustring(aStr, aSearchStr, 8);
753         }
754 
755     void lastIndexOf_test_oustring_005()
756         {
757             // search for sun, found (pos==4)
758             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun su");
759             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
760             lastIndexOf_oustring(aStr, aSearchStr, 4);
761         }
762 
763     void lastIndexOf_test_oustring_006()
764         {
765             // search for sun, found (pos==-1)
766             rtl::OUString aStr = rtl::OUString::createFromAscii("the su su");
767             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("sun");
768             lastIndexOf_oustring(aStr, aSearchStr, -1);
769         }
770 
771     void lastIndexOf_test_oustring_007()
772         {
773             // search for earth, not found (-1)
774             rtl::OUString aStr = rtl::OUString::createFromAscii("the su su");
775             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("earth");
776             lastIndexOf_oustring(aStr, aSearchStr, -1);
777         }
778 
779     void lastIndexOf_test_oustring_008()
780         {
781             // search for earth, not found (-1)
782             rtl::OUString aStr = rtl::OUString();
783             rtl::OUString aSearchStr = rtl::OUString::createFromAscii("earth");
784             lastIndexOf_oustring(aStr, aSearchStr, -1);
785         }
786 
787     void lastIndexOf_test_oustring_009()
788         {
789             // search for earth, not found (-1)
790             rtl::OUString aStr = rtl::OUString();
791             rtl::OUString aSearchStr = rtl::OUString();
792             lastIndexOf_oustring(aStr, aSearchStr, -1);
793 
794         }
795 
796     void lastIndexOf_test_salunicode_001()
797         {
798             // search for 's', found (19)
799             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun sun java system");
800             sal_Unicode suChar = L's';
801             lastIndexOf_salunicode(aStr, suChar, 19);
802         }
803 
804     void lastIndexOf_test_salunicode_002()
805         {
806             // search for 'x', not found (-1)
807             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun sun java system");
808             sal_Unicode suChar = L'x';
809             lastIndexOf_salunicode(aStr, suChar, -1);
810         }
811 
812     void lastIndexOf_test_salunicode_offset_001()
813         {
814             // search for 's', start from pos last char, found (19)
815             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun sun java system");
816             sal_Unicode cuChar = L's';
817             lastIndexOf_salunicode_offset(aStr, cuChar, 19, aStr.getLength());
818         }
819     void lastIndexOf_test_salunicode_offset_002()
820         {
821             // search for 's', start pos is last occur from search behind, found (17)
822             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun sun java system");
823             sal_Unicode cuChar = L's';
824             lastIndexOf_salunicode_offset(aStr, cuChar, 17, 19);
825         }
826     void lastIndexOf_test_salunicode_offset_003()
827         {
828             // search for 't', start pos is 1, found (0)
829             rtl::OUString aStr = rtl::OUString::createFromAscii("the sun sun java system");
830             sal_Unicode cuChar = L't';
831             lastIndexOf_salunicode_offset(aStr, cuChar, 0, 1);
832         }
833 
834     // Change the following lines only, if you add, remove or rename
835     // member functions of the current class,
836     // because these macros are need by auto register mechanism.
837 
838     CPPUNIT_TEST_SUITE(lastIndexOf);
839     CPPUNIT_TEST(lastIndexOf_test_oustring_001);
840     CPPUNIT_TEST(lastIndexOf_test_oustring_002);
841     CPPUNIT_TEST(lastIndexOf_test_oustring_003);
842     CPPUNIT_TEST(lastIndexOf_test_oustring_004);
843     CPPUNIT_TEST(lastIndexOf_test_oustring_005);
844     CPPUNIT_TEST(lastIndexOf_test_oustring_006);
845     CPPUNIT_TEST(lastIndexOf_test_oustring_007);
846     CPPUNIT_TEST(lastIndexOf_test_oustring_008);
847     CPPUNIT_TEST(lastIndexOf_test_oustring_009);
848 
849     CPPUNIT_TEST(lastIndexOf_test_oustring_offset_001);
850     CPPUNIT_TEST(lastIndexOf_test_oustring_offset_002);
851     CPPUNIT_TEST(lastIndexOf_test_oustring_offset_003);
852     CPPUNIT_TEST(lastIndexOf_test_oustring_offset_004);
853 
854     CPPUNIT_TEST(lastIndexOf_test_salunicode_001);
855     CPPUNIT_TEST(lastIndexOf_test_salunicode_002);
856 
857     CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_001);
858     CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_002);
859     CPPUNIT_TEST(lastIndexOf_test_salunicode_offset_003);
860 
861     CPPUNIT_TEST_SUITE_END();
862 }; // class lastIndexOf
863 
864 
865 // -----------------------------------------------------------------------------
866 // - getToken (tests)
867 // -----------------------------------------------------------------------------
868 class getToken : public CppUnit::TestFixture
869 {
870 
871 public:
872     void getToken_000()
873         {
874             rtl::OUString suTokenStr;
875 
876             sal_Int32 nIndex = 0;
877             do
878             {
879                 rtl::OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
880             }
881             while ( nIndex >= 0 );
882             t_print("Index %d\n", nIndex);
883             // should not GPF
884         }
885 
886     void getToken_001()
887         {
888             rtl::OUString suTokenStr = rtl::OUString::createFromAscii("a;b");
889 
890             sal_Int32 nIndex = 0;
891 
892             rtl::OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
893             CPPUNIT_ASSERT_MESSAGE("Token should be a 'a'", suToken.equals(rtl::OUString::createFromAscii("a")) == sal_True);
894 
895             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
896             CPPUNIT_ASSERT_MESSAGE("Token should be a 'b'", suToken.equals(rtl::OUString::createFromAscii("b")) == sal_True);
897             CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
898         }
899 
900     void getToken_002()
901         {
902             rtl::OUString suTokenStr = rtl::OUString::createFromAscii("a;b.c");
903 
904             sal_Int32 nIndex = 0;
905 
906             rtl::OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
907             CPPUNIT_ASSERT_MESSAGE("Token should be a 'a'", suToken.equals(rtl::OUString::createFromAscii("a")) == sal_True);
908 
909             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
910             CPPUNIT_ASSERT_MESSAGE("Token should be a 'b'", suToken.equals(rtl::OUString::createFromAscii("b")) == sal_True);
911 
912             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
913             CPPUNIT_ASSERT_MESSAGE("Token should be a 'c'", suToken.equals(rtl::OUString::createFromAscii("c")) == sal_True);
914             CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
915         }
916 
917     void getToken_003()
918         {
919             rtl::OUString suTokenStr = rtl::OUString::createFromAscii("a;;b");
920 
921             sal_Int32 nIndex = 0;
922 
923             rtl::OUString suToken = suTokenStr.getToken( 0, ';', nIndex );
924             CPPUNIT_ASSERT_MESSAGE("Token should be a 'a'", suToken.equals(rtl::OUString::createFromAscii("a")) == sal_True);
925 
926             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
927             CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.getLength() == 0);
928 
929             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, ';', nIndex );
930             CPPUNIT_ASSERT_MESSAGE("Token should be a 'b'", suToken.equals(rtl::OUString::createFromAscii("b")) == sal_True);
931             CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
932         }
933 
934     void getToken_004()
935         {
936             rtl::OUString suTokenStr = rtl::OUString::createFromAscii("longer.then.ever.");
937 
938             sal_Int32 nIndex = 0;
939 
940             rtl::OUString suToken = suTokenStr.getToken( 0, '.', nIndex );
941             CPPUNIT_ASSERT_MESSAGE("Token should be 'longer'", suToken.equals(rtl::OUString::createFromAscii("longer")) == sal_True);
942 
943             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
944             CPPUNIT_ASSERT_MESSAGE("Token should be 'then'", suToken.equals(rtl::OUString::createFromAscii("then")) == sal_True);
945 
946             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
947             CPPUNIT_ASSERT_MESSAGE("Token should be 'ever'", suToken.equals(rtl::OUString::createFromAscii("ever")) == sal_True);
948 
949             /* rtl::OUString */ suToken = suTokenStr.getToken( 0, '.', nIndex );
950             CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.getLength() == 0);
951 
952             CPPUNIT_ASSERT_MESSAGE("index should be negative", nIndex == -1);
953         }
954 
955     void getToken_005() {
956         rtl::OUString ab(RTL_CONSTASCII_USTRINGPARAM("ab"));
957         sal_Int32 n = 0;
958         CPPUNIT_ASSERT_MESSAGE(
959             "token should be 'ab'", ab.getToken(0, '-', n) == ab);
960         CPPUNIT_ASSERT_MESSAGE("n should be -1", n == -1);
961         CPPUNIT_ASSERT_MESSAGE(
962             "token should be empty", ab.getToken(0, '-', n).getLength() == 0);
963     }
964 
965     CPPUNIT_TEST_SUITE(getToken);
966     CPPUNIT_TEST(getToken_000);
967     CPPUNIT_TEST(getToken_001);
968     CPPUNIT_TEST(getToken_002);
969     CPPUNIT_TEST(getToken_003);
970     CPPUNIT_TEST(getToken_004);
971     CPPUNIT_TEST(getToken_005);
972     CPPUNIT_TEST_SUITE_END();
973 }; // class getToken
974 
975 class convertToString: public CppUnit::TestFixture {
976 public:
977     void test();
978 
979     CPPUNIT_TEST_SUITE(convertToString);
980     CPPUNIT_TEST(test);
981     CPPUNIT_TEST_SUITE_END();
982 };
983 
984 void convertToString::test() {
985     static sal_Unicode const utf16[] = { 0x0041, 0x00E4, 0x0061 };
986     rtl::OString s;
987     CPPUNIT_ASSERT(
988         rtl::OUString(utf16, sizeof utf16 / sizeof utf16[0]).convertToString(
989             &s, RTL_TEXTENCODING_UTF7,
990             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
991              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)));
992     CPPUNIT_ASSERT_EQUAL(
993         rtl::OString(RTL_CONSTASCII_STRINGPARAM("A+AOQ-a")), s);
994 }
995 
996 // -----------------------------------------------------------------------------
997 // - string construction & interning (tests)
998 // -----------------------------------------------------------------------------
999 class construction : public CppUnit::TestFixture
1000 {
1001 public:
1002     void construct()
1003     {
1004 #ifdef RTL_INLINE_STRINGS
1005         ::rtl::OUString aFoo( RTL_CONSTASCII_USTRINGPARAM("foo") );
1006         CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[0] == 'f');
1007         CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[1] == 'o');
1008         CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[2] == 'o');
1009         CPPUNIT_ASSERT_MESSAGE("string length", aFoo.getLength() == 3);
1010 
1011         ::rtl::OUString aBaa( RTL_CONSTASCII_USTRINGPARAM("this is a very long string with a lot of long things inside it and it goes on and on and on forever etc.") );
1012         CPPUNIT_ASSERT_MESSAGE("string length", aBaa.getLength() == 104);
1013         // Dig at the internals ... FIXME: should we have the bit-flag defines public ?
1014         CPPUNIT_ASSERT_MESSAGE("string static flags", (aBaa.pData->refCount & 1<<30) != 0);
1015 #endif
1016     }
1017 
1018     void intern()
1019     {
1020         // The empty string is 'static' a special case ...
1021         rtl::OUString aEmpty = rtl::OUString().intern();
1022         rtl::OUString aEmpty2 = rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "" ) );
1023 
1024         ::rtl::OUString aFoo( RTL_CONSTASCII_USTRINGPARAM("foo") );
1025         ::rtl::OUString aFooIntern = aFoo.intern();
1026         CPPUNIT_ASSERT_MESSAGE("string contents", aFooIntern.equalsAscii("foo"));
1027         CPPUNIT_ASSERT_MESSAGE("string length", aFooIntern.getLength() == 3);
1028         // We have to dup due to no atomic 'intern' bit-set operation
1029         CPPUNIT_ASSERT_MESSAGE("intern dups", aFoo.pData != aFooIntern.pData);
1030 
1031         // Test interning lots of things
1032         int i;
1033         static const int nSequence = 4096;
1034         rtl::OUString *pStrs;
1035         sal_uIntPtr   *pValues;
1036 
1037         pStrs = new rtl::OUString[nSequence];
1038         pValues = new sal_uIntPtr[nSequence];
1039         for (i = 0; i < nSequence; i++)
1040         {
1041             pStrs[i] = rtl::OUString::valueOf( sqrt( static_cast<double>(i) ) ).intern();
1042             pValues[i] = reinterpret_cast<sal_uIntPtr>( pStrs[i].pData );
1043         }
1044         for (i = 0; i < nSequence; i++)
1045         {
1046             rtl::OUString aNew = rtl::OUString::valueOf( sqrt( static_cast<double>(i) ) ).intern();
1047             CPPUNIT_ASSERT_MESSAGE("double intern failed",
1048                                    aNew.pData == pStrs[i].pData);
1049         }
1050 
1051         // Free strings to check for leaks
1052         for (i = 0; i < nSequence; i++)
1053         {
1054             // Overwrite - hopefully this re-uses the memory
1055             pStrs[i] = rtl::OUString();
1056             pStrs[i] = rtl::OUString::valueOf( sqrt( static_cast<double>(i) ) );
1057         }
1058 
1059         for (i = 0; i < nSequence; i++)
1060         {
1061             rtl::OUString aIntern;
1062             sal_uIntPtr nValue;
1063             aIntern = rtl::OUString::valueOf( sqrt( static_cast<double>(i) ) ).intern();
1064 
1065             nValue = reinterpret_cast<sal_uIntPtr>( aIntern.pData );
1066             // This may not be 100% reliable: memory may
1067             // have been re-used, but it's worth checking.
1068             CPPUNIT_ASSERT_MESSAGE("intern leaking", nValue != pValues[i]);
1069         }
1070         delete [] pValues;
1071         delete [] pStrs;
1072     }
1073 
1074     CPPUNIT_TEST_SUITE(construction);
1075     CPPUNIT_TEST(construct);
1076     CPPUNIT_TEST(intern);
1077     CPPUNIT_TEST_SUITE_END();
1078 };
1079 
1080 class indexOfAscii: public CppUnit::TestFixture {
1081 public:
1082     void test();
1083 
1084     CPPUNIT_TEST_SUITE(indexOfAscii);
1085     CPPUNIT_TEST(test);
1086     CPPUNIT_TEST_SUITE_END();
1087 };
1088 
1089 void indexOfAscii::test() {
1090     CPPUNIT_ASSERT_EQUAL(
1091         sal_Int32(-1),
1092         rtl::OUString().indexOfAsciiL(RTL_CONSTASCII_STRINGPARAM("")));
1093     CPPUNIT_ASSERT_EQUAL(
1094         sal_Int32(-1),
1095         rtl::OUString().lastIndexOfAsciiL(RTL_CONSTASCII_STRINGPARAM("")));
1096     CPPUNIT_ASSERT_EQUAL(
1097         sal_Int32(0),
1098         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo")).indexOfAsciiL(
1099             RTL_CONSTASCII_STRINGPARAM("foo")));
1100     CPPUNIT_ASSERT_EQUAL(
1101         sal_Int32(0),
1102         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo")).lastIndexOfAsciiL(
1103             RTL_CONSTASCII_STRINGPARAM("foo")));
1104     CPPUNIT_ASSERT_EQUAL(
1105         sal_Int32(2),
1106         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("fofoobar")).indexOfAsciiL(
1107             RTL_CONSTASCII_STRINGPARAM("foo")));
1108     CPPUNIT_ASSERT_EQUAL(
1109         sal_Int32(3),
1110         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foofoofob")).
1111         lastIndexOfAsciiL(RTL_CONSTASCII_STRINGPARAM("foo")));
1112     CPPUNIT_ASSERT_EQUAL(
1113         sal_Int32(3),
1114         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foofoobar")).indexOfAsciiL(
1115             RTL_CONSTASCII_STRINGPARAM("foo"), 1));
1116 }
1117 
1118 class endsWith: public CppUnit::TestFixture {
1119 public:
1120     void test();
1121 
1122     CPPUNIT_TEST_SUITE(endsWith);
1123     CPPUNIT_TEST(test);
1124     CPPUNIT_TEST_SUITE_END();
1125 };
1126 
1127 void endsWith::test() {
1128     CPPUNIT_ASSERT_EQUAL(
1129         true,
1130         rtl::OUString().endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM("")));
1131     CPPUNIT_ASSERT_EQUAL(
1132         false,
1133         rtl::OUString().endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM("foo")));
1134     CPPUNIT_ASSERT_EQUAL(
1135         true,
1136         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bar")).endsWithAsciiL(
1137             RTL_CONSTASCII_STRINGPARAM("bar")));
1138     CPPUNIT_ASSERT_EQUAL(
1139         true,
1140         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foobar")).endsWithAsciiL(
1141             RTL_CONSTASCII_STRINGPARAM("bar")));
1142     CPPUNIT_ASSERT_EQUAL(
1143         false,
1144         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FOOBAR")).endsWithAsciiL(
1145             RTL_CONSTASCII_STRINGPARAM("bar")));
1146 }
1147 
1148 class createFromCodePoints: public CppUnit::TestFixture {
1149 public:
1150     void test();
1151 
1152     CPPUNIT_TEST_SUITE(createFromCodePoints);
1153     CPPUNIT_TEST(test);
1154     CPPUNIT_TEST_SUITE_END();
1155 };
1156 
1157 void createFromCodePoints::test() {
1158     CPPUNIT_ASSERT_EQUAL(
1159         sal_Int32(0),
1160         rtl::OUString(static_cast< sal_uInt32 const * >(NULL), 0).getLength());
1161     static sal_uInt32 const cp[] = { 0, 0xD800, 0xFFFF, 0x10000, 0x10FFFF };
1162     rtl::OUString s(cp, sizeof cp / sizeof (sal_uInt32));
1163     CPPUNIT_ASSERT_EQUAL(sal_Int32(7), s.getLength());
1164     CPPUNIT_ASSERT_EQUAL(sal_Unicode(0), s[0]);
1165     CPPUNIT_ASSERT_EQUAL(sal_Unicode(0xD800), s[1]);
1166     CPPUNIT_ASSERT_EQUAL(sal_Unicode(0xFFFF), s[2]);
1167     CPPUNIT_ASSERT_EQUAL(sal_Unicode(0xD800), s[3]);
1168     CPPUNIT_ASSERT_EQUAL(sal_Unicode(0xDC00), s[4]);
1169     CPPUNIT_ASSERT_EQUAL(sal_Unicode(0xDBFF), s[5]);
1170     CPPUNIT_ASSERT_EQUAL(sal_Unicode(0xDFFF), s[6]);
1171 }
1172 
1173 class iterateCodePoints: public CppUnit::TestFixture {
1174 public:
1175     void testNotWellFormed();
1176 
1177     CPPUNIT_TEST_SUITE(iterateCodePoints);
1178     CPPUNIT_TEST(testNotWellFormed);
1179     CPPUNIT_TEST_SUITE_END();
1180 };
1181 
1182 void iterateCodePoints::testNotWellFormed() {
1183     static sal_Unicode const utf16[] =
1184         { 0xD800, 0xDC00, 0x0041, 0xDBFF, 0xDFFF, 0xDDEF, 0xD9AB };
1185     rtl::OUString s(utf16, sizeof utf16 / sizeof (sal_Unicode));
1186     sal_Int32 i = 0;
1187     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i));
1188     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i);
1189     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i));
1190     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
1191     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i));
1192     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i);
1193     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i));
1194     CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i);
1195     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i));
1196     CPPUNIT_ASSERT_EQUAL(sal_Int32(7), i);
1197     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xD9AB), s.iterateCodePoints(&i, -1));
1198     CPPUNIT_ASSERT_EQUAL(sal_Int32(6), i);
1199     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDDEF), s.iterateCodePoints(&i, -1));
1200     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), i);
1201     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10FFFF), s.iterateCodePoints(&i, -1));
1202     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
1203     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0041), s.iterateCodePoints(&i, -1));
1204     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), i);
1205     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -1));
1206     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
1207     i = 1;
1208     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xDC00), s.iterateCodePoints(&i, 2));
1209     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), i);
1210     i = 4;
1211     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x10000), s.iterateCodePoints(&i, -3));
1212     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), i);
1213 }
1214 
1215 class convertFromString: public CppUnit::TestFixture {
1216 public:
1217     void test();
1218 
1219     CPPUNIT_TEST_SUITE(createFromCodePoints);
1220     CPPUNIT_TEST(test);
1221     CPPUNIT_TEST_SUITE_END();
1222 };
1223 
1224 void convertFromString::test() {
1225     rtl::OUString t;
1226     CPPUNIT_ASSERT(
1227         !rtl_convertStringToUString(
1228             &t.pData, RTL_CONSTASCII_STRINGPARAM("\x80"), RTL_TEXTENCODING_UTF8,
1229             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1230              RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1231              RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1232     CPPUNIT_ASSERT(
1233         !rtl_convertStringToUString(
1234             &t.pData, RTL_CONSTASCII_STRINGPARAM("\xC0"), RTL_TEXTENCODING_UTF8,
1235             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1236              RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1237              RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1238     CPPUNIT_ASSERT(
1239         !rtl_convertStringToUString(
1240             &t.pData, RTL_CONSTASCII_STRINGPARAM("\xFF"), RTL_TEXTENCODING_UTF8,
1241             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1242              RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1243              RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1244     CPPUNIT_ASSERT(
1245         rtl_convertStringToUString(
1246             &t.pData, RTL_CONSTASCII_STRINGPARAM("abc"), RTL_TEXTENCODING_UTF8,
1247             (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
1248              RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
1249              RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
1250     CPPUNIT_ASSERT(t.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("abc")));
1251 }
1252 
1253 // -----------------------------------------------------------------------------
1254 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::valueOf, "rtl_OUString");
1255 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::toInt, "rtl_OUString");
1256 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::toDouble, "rtl_OUString");
1257 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::toFloat, "rtl_OUString");
1258 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::lastIndexOf, "rtl_OUString");
1259 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::getToken, "rtl_OUString");
1260 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(
1261     rtl_OUString::convertToString, "rtl_OUString");
1262 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::construction, "rtl_OUString");
1263 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(
1264     rtl_OUString::indexOfAscii, "rtl_OUString");
1265 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::endsWith, "rtl_OUString");
1266 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(
1267     rtl_OUString::createFromCodePoints, "rtl_OUString");
1268 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(
1269     rtl_OUString::iterateCodePoints, "rtl_OUString");
1270 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(
1271     rtl_OUString::convertFromString, "rtl_OUString");
1272 
1273 } // namespace rtl_OUString
1274 
1275 
1276 // -----------------------------------------------------------------------------
1277 
1278 // this macro creates an empty function, which will called by the RegisterAllFunctions()
1279 // to let the user the possibility to also register some functions by hand.
1280 NOADDITIONAL;
1281