My Project
UDK 3.2.7 C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ustring.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef _RTL_USTRING_HXX_
21 #define _RTL_USTRING_HXX_
22 
23 #include "sal/config.h"
24 
25 #include <cassert>
26 #include <ostream>
27 #include <string.h>
28 
29 #include "osl/diagnose.h"
30 #include <rtl/ustring.h>
31 #include <rtl/string.hxx>
32 #include <rtl/stringutils.hxx>
33 #include <rtl/textenc.h>
34 #include "sal/log.hxx"
35 
36 #ifdef RTL_FAST_STRING
37 #include <rtl/stringconcat.hxx>
38 #endif
39 
40 #if defined EXCEPTIONS_OFF
41 #include <stdlib.h>
42 #else
43 #include <new>
44 #endif
45 
46 // The unittest uses slightly different code to help check that the proper
47 // calls are made. The class is put into a different namespace to make
48 // sure the compiler generates a different (if generating also non-inline)
49 // copy of the function and does not merge them together. The class
50 // is "brought" into the proper rtl namespace by a typedef below.
51 #ifdef RTL_STRING_UNITTEST
52 #define rtl rtlunittest
53 #endif
54 
55 namespace rtl
56 {
57 
58 #ifdef RTL_STRING_UNITTEST
59 #undef rtl
60 #endif
61 
62 /* ======================================================================= */
63 
88 {
89 public:
91  rtl_uString * pData;
93 
94 private:
95  class DO_NOT_ACQUIRE{};
96 
97  OUString( rtl_uString * value, SAL_UNUSED_PARAMETER DO_NOT_ACQUIRE * )
98  {
99  pData = value;
100  }
101 
102 public:
107  {
108  pData = 0;
109  rtl_uString_new( &pData );
110  }
111 
117  OUString( const OUString & str ) SAL_THROW(())
118  {
119  pData = str.pData;
120  rtl_uString_acquire( pData );
121  }
122 
128  OUString( rtl_uString * str ) SAL_THROW(())
129  {
130  pData = str;
131  rtl_uString_acquire( pData );
132  }
133 
142  inline OUString( rtl_uString * str, __sal_NoAcquire ) SAL_THROW(())
143  { pData = str; }
144 
150  explicit OUString( sal_Unicode value ) SAL_THROW(())
151  : pData (0)
152  {
153  rtl_uString_newFromStr_WithLength( &pData, &value, 1 );
154  }
155 
161  OUString( const sal_Unicode * value ) SAL_THROW(())
162  {
163  pData = 0;
164  rtl_uString_newFromStr( &pData, value );
165  }
166 
175  OUString( const sal_Unicode * value, sal_Int32 length ) SAL_THROW(())
176  {
177  pData = 0;
178  rtl_uString_newFromStr_WithLength( &pData, value, length );
179  }
180 
196 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
197  // Old gcc can try to convert anonymous enums to OUString and give compile error.
198  // So instead have a variant for const and non-const char[].
199  template< int N >
200  OUString( const char (&literal)[ N ] )
201  {
202  // Check that the string literal is in fact N - 1 long (no embedded \0's),
203  // any decent compiler should optimize out calls to strlen with literals.
204  assert( strlen( literal ) == N - 1 );
205  pData = 0;
206  rtl_uString_newFromLiteral( &pData, literal, N - 1, 0 );
207 #ifdef RTL_STRING_UNITTEST
208  rtl_string_unittest_const_literal = true;
209 #endif
210  }
211 
216  template< int N >
217  OUString( char (&value)[ N ] )
218 #ifndef RTL_STRING_UNITTEST
219  ; // intentionally not implemented
220 #else
221  {
222  (void) value; // unused
223  pData = 0;
224  rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
225  rtl_string_unittest_invalid_conversion = true;
226  }
227 #endif
228 #else // HAVE_SFINAE_ANONYMOUS_BROKEN
229  template< typename T >
231  {
232  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
233  pData = 0;
235 #ifdef RTL_STRING_UNITTEST
236  rtl_string_unittest_const_literal = true;
237 #endif
238  }
239 
240 #endif // HAVE_SFINAE_ANONYMOUS_BROKEN
241 
242 
243 #ifdef RTL_STRING_UNITTEST
244 
248  template< typename T >
250  {
251  pData = 0;
252  rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
253  rtl_string_unittest_invalid_conversion = true;
254  }
259  template< typename T >
260  OUString( const T&, typename internal::ExceptCharArrayDetector< T >::Type = internal::Dummy() )
261  {
262  pData = 0;
263  rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
264  rtl_string_unittest_invalid_conversion = true;
265  }
266 #endif
267 
282  OUString( const sal_Char * value, sal_Int32 length,
283  rtl_TextEncoding encoding,
284  sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS )
285  {
286  pData = 0;
287  rtl_string2UString( &pData, value, length, encoding, convertFlags );
288  if (pData == 0) {
289 #if defined EXCEPTIONS_OFF
290  abort();
291 #else
292  throw std::bad_alloc();
293 #endif
294  }
295  }
296 
313  inline explicit OUString(
314  sal_uInt32 const * codePoints, sal_Int32 codePointCount):
315  pData(NULL)
316  {
317  rtl_uString_newFromCodePoints(&pData, codePoints, codePointCount);
318  if (pData == NULL) {
319 #if defined EXCEPTIONS_OFF
320  abort();
321 #else
322  throw std::bad_alloc();
323 #endif
324  }
325  }
326 
327 #ifdef RTL_FAST_STRING
328  template< typename T1, typename T2 >
329  OUString( const OUStringConcat< T1, T2 >& c )
330  {
331  const sal_Int32 l = c.length();
332  rtl_uString* buffer = NULL;
333  rtl_uString_new_WithLength( &buffer, l ); // TODO this clears, not necessary
334  if (l != 0)
335  {
336  sal_Unicode* end = c.addData( buffer->buffer );
337  buffer->length = end - buffer->buffer;
338  // TODO realloc in case buffer->length is noticeably smaller than l?
339  }
340  pData = buffer;
341  }
342 #endif
343 
348  {
349  rtl_uString_release( pData );
350  }
351 
363  static inline OUString const & unacquired( rtl_uString * const * ppHandle )
364  { return * reinterpret_cast< OUString const * >( ppHandle ); }
365 
371  OUString & operator=( const OUString & str ) SAL_THROW(())
372  {
373  rtl_uString_assign( &pData, str.pData );
374  return *this;
375  }
376 
389  template< typename T >
391  {
392  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
394  return *this;
395  }
396 
402  OUString & operator+=( const OUString & str ) SAL_THROW(())
403  {
404  rtl_uString_newConcat( &pData, pData, str.pData );
405  return *this;
406  }
407 
416  sal_Int32 getLength() const SAL_THROW(()) { return pData->length; }
417 
426  bool isEmpty() const SAL_THROW(())
427  {
428  return pData->length == 0;
429  }
430 
438  const sal_Unicode * getStr() const SAL_THROW(()) { return pData->buffer; }
439 
449  sal_Unicode operator [](sal_Int32 index) const { return getStr()[index]; }
450 
463  sal_Int32 compareTo( const OUString & str ) const SAL_THROW(())
464  {
465  return rtl_ustr_compare_WithLength( pData->buffer, pData->length,
466  str.pData->buffer, str.pData->length );
467  }
468 
484  sal_Int32 compareTo( const OUString & str, sal_Int32 maxLength ) const SAL_THROW(())
485  {
486  return rtl_ustr_shortenedCompare_WithLength( pData->buffer, pData->length,
487  str.pData->buffer, str.pData->length, maxLength );
488  }
489 
502  sal_Int32 reverseCompareTo( const OUString & str ) const SAL_THROW(())
503  {
504  return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length,
505  str.pData->buffer, str.pData->length );
506  }
507 
519  sal_Bool equals( const OUString & str ) const SAL_THROW(())
520  {
521  if ( pData->length != str.pData->length )
522  return sal_False;
523  if ( pData == str.pData )
524  return sal_True;
525  return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length,
526  str.pData->buffer, str.pData->length ) == 0;
527  }
528 
543  sal_Bool equalsIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
544  {
545  if ( pData->length != str.pData->length )
546  return sal_False;
547  if ( pData == str.pData )
548  return sal_True;
549  return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
550  str.pData->buffer, str.pData->length ) == 0;
551  }
552 
568  sal_Int32 compareToIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
569  {
570  return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
571  str.pData->buffer, str.pData->length );
572  }
573 
574 
580  template< typename T >
581  typename internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(())
582  {
583  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
584  if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 )
585  return sal_False;
586 
587  return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, literal ) == 0;
588  }
589 
605  sal_Bool match( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
606  {
607  return rtl_ustr_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
608  str.pData->buffer, str.pData->length, str.pData->length ) == 0;
609  }
610 
616  template< typename T >
617  typename internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
618  {
619  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
620  return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
622  }
623 
642  sal_Bool matchIgnoreAsciiCase( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
643  {
644  return rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
645  str.pData->buffer, str.pData->length,
646  str.pData->length ) == 0;
647  }
648 
654  template< typename T >
655  typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
656  {
657  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
658  return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
660  }
661 
678  sal_Int32 compareToAscii( const sal_Char* asciiStr ) const SAL_THROW(())
679  {
680  return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, asciiStr );
681  }
682 
700  sal_Int32 compareToAscii( const sal_Char * asciiStr, sal_Int32 maxLength ) const SAL_THROW(())
701  {
702  return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer, pData->length,
703  asciiStr, maxLength );
704  }
705 
725  sal_Int32 reverseCompareToAsciiL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
726  {
727  return rtl_ustr_asciil_reverseCompare_WithLength( pData->buffer, pData->length,
728  asciiStr, asciiStrLength );
729  }
730 
746  sal_Bool equalsAscii( const sal_Char* asciiStr ) const SAL_THROW(())
747  {
748  return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length,
749  asciiStr ) == 0;
750  }
751 
769  sal_Bool equalsAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
770  {
771  if ( pData->length != asciiStrLength )
772  return sal_False;
773 
775  pData->buffer, asciiStr, asciiStrLength );
776  }
777 
796  sal_Bool equalsIgnoreAsciiCaseAscii( const sal_Char * asciiStr ) const SAL_THROW(())
797  {
798  return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0;
799  }
800 
819  sal_Int32 compareToIgnoreAsciiCaseAscii( const sal_Char * asciiStr ) const SAL_THROW(())
820  {
821  return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr );
822  }
823 
844  sal_Bool equalsIgnoreAsciiCaseAsciiL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
845  {
846  if ( pData->length != asciiStrLength )
847  return sal_False;
848 
849  return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0;
850  }
851 
873  sal_Bool matchAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
874  {
875  return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
876  asciiStr, asciiStrLength ) == 0;
877  }
878 
879  // This overload is left undefined, to detect calls of matchAsciiL that
880  // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
881  // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
882  // platforms):
883 #if SAL_TYPES_SIZEOFLONG == 8
884  void matchAsciiL(char const *, sal_Int32, rtl_TextEncoding) const;
885 #endif
886 
911  sal_Bool matchIgnoreAsciiCaseAsciiL( const sal_Char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
912  {
913  return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
914  asciiStr, asciiStrLength ) == 0;
915  }
916 
917  // This overload is left undefined, to detect calls of
918  // matchIgnoreAsciiCaseAsciiL that erroneously use
919  // RTL_CONSTASCII_USTRINGPARAM instead of RTL_CONSTASCII_STRINGPARAM (but
920  // would lead to ambiguities on 32 bit platforms):
921 #if SAL_TYPES_SIZEOFLONG == 8
922  void matchIgnoreAsciiCaseAsciiL(char const *, sal_Int32, rtl_TextEncoding)
923  const;
924 #endif
925 
936  bool startsWith(OUString const & str) const {
937  return match(str, 0);
938  }
939 
945  template< typename T >
946  typename internal::ConstCharArrayDetector< T, bool >::Type startsWith( T& literal ) const
947  {
948  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
949  return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
950  && rtl_ustr_asciil_reverseEquals_WithLength( pData->buffer, literal,
952  }
953 
967  sal_Bool startsWithIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
968  {
969  return matchIgnoreAsciiCase(str, 0);
970  }
971 
977  template< typename T >
978  typename internal::ConstCharArrayDetector< T, bool >::Type startsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(())
979  {
980  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
982  pData->buffer,
985  == 0);
986  }
987 
998  bool endsWith(OUString const & str) const {
999  return str.getLength() <= getLength()
1000  && match(str, getLength() - str.getLength());
1001  }
1002 
1008  template< typename T >
1009  typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const
1010  {
1011  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1012  return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
1014  pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ), literal,
1016  }
1017 
1029  inline bool endsWithAsciiL(char const * asciiStr, sal_Int32 asciiStrLength)
1030  const
1031  {
1032  return asciiStrLength <= pData->length
1034  pData->buffer + pData->length - asciiStrLength, asciiStr,
1035  asciiStrLength);
1036  }
1037 
1051  sal_Bool endsWithIgnoreAsciiCase( const OUString & str ) const SAL_THROW(())
1052  {
1053  return str.getLength() <= getLength()
1054  && matchIgnoreAsciiCase(str, getLength() - str.getLength());
1055  }
1056 
1062  template< typename T >
1063  typename internal::ConstCharArrayDetector< T, bool >::Type endsWithIgnoreAsciiCase( T& literal ) const SAL_THROW(())
1064  {
1065  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1066  return internal::ConstCharArrayDetector< T, void >::size - 1 <= pData->length
1068  pData->buffer + pData->length - ( internal::ConstCharArrayDetector< T, void >::size - 1 ),
1071  == 0);
1072  }
1073 
1084  inline bool endsWithIgnoreAsciiCaseAsciiL(
1085  char const * asciiStr, sal_Int32 asciiStrLength) const
1086  {
1087  return asciiStrLength <= pData->length
1089  pData->buffer + pData->length - asciiStrLength,
1090  asciiStrLength, asciiStr, asciiStrLength)
1091  == 0);
1092  }
1093 
1094  friend sal_Bool operator == ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
1095  { return rStr1.equals(rStr2); }
1096  friend sal_Bool operator == ( const OUString& rStr1, const sal_Unicode * pStr2 ) SAL_THROW(())
1097  { return rStr1.compareTo( pStr2 ) == 0; }
1098  friend sal_Bool operator == ( const sal_Unicode * pStr1, const OUString& rStr2 ) SAL_THROW(())
1099  { return OUString( pStr1 ).compareTo( rStr2 ) == 0; }
1100 
1101  friend sal_Bool operator != ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
1102  { return !(operator == ( rStr1, rStr2 )); }
1103  friend sal_Bool operator != ( const OUString& rStr1, const sal_Unicode * pStr2 ) SAL_THROW(())
1104  { return !(operator == ( rStr1, pStr2 )); }
1105  friend sal_Bool operator != ( const sal_Unicode * pStr1, const OUString& rStr2 ) SAL_THROW(())
1106  { return !(operator == ( pStr1, rStr2 )); }
1107 
1108  friend sal_Bool operator < ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
1109  { return rStr1.compareTo( rStr2 ) < 0; }
1110  friend sal_Bool operator > ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
1111  { return rStr1.compareTo( rStr2 ) > 0; }
1112  friend sal_Bool operator <= ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
1113  { return rStr1.compareTo( rStr2 ) <= 0; }
1114  friend sal_Bool operator >= ( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
1115  { return rStr1.compareTo( rStr2 ) >= 0; }
1116 
1124  template< typename T >
1125  friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& string, T& literal )
1126  {
1127  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1128  return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
1129  }
1137  template< typename T >
1138  friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& string )
1139  {
1140  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1141  return string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
1142  }
1150  template< typename T >
1151  friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& string, T& literal )
1152  {
1153  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1154  return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
1155  }
1163  template< typename T >
1164  friend inline typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& string )
1165  {
1166  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1167  return !string.equalsAsciiL( literal, internal::ConstCharArrayDetector< T, void >::size - 1 );
1168  }
1169 
1177  sal_Int32 hashCode() const SAL_THROW(())
1178  {
1179  return rtl_ustr_hashCode_WithLength( pData->buffer, pData->length );
1180  }
1181 
1195  sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
1196  {
1197  sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
1198  return (ret < 0 ? ret : ret+fromIndex);
1199  }
1200 
1210  sal_Int32 lastIndexOf( sal_Unicode ch ) const SAL_THROW(())
1211  {
1212  return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
1213  }
1214 
1227  sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const SAL_THROW(())
1228  {
1229  return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
1230  }
1231 
1247  sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
1248  {
1249  sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1250  str.pData->buffer, str.pData->length );
1251  return (ret < 0 ? ret : ret+fromIndex);
1252  }
1253 
1259  template< typename T >
1260  typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
1261  {
1262  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1263  sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
1264  pData->buffer + fromIndex, pData->length - fromIndex, literal,
1266  return ret < 0 ? ret : ret + fromIndex;
1267  }
1268 
1292  sal_Int32 indexOfAsciiL(
1293  char const * str, sal_Int32 len, sal_Int32 fromIndex = 0) const
1294  SAL_THROW(())
1295  {
1296  sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
1297  pData->buffer + fromIndex, pData->length - fromIndex, str, len);
1298  return ret < 0 ? ret : ret + fromIndex;
1299  }
1300 
1301  // This overload is left undefined, to detect calls of indexOfAsciiL that
1302  // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
1303  // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
1304  // platforms):
1305 #if SAL_TYPES_SIZEOFLONG == 8
1306  void indexOfAsciiL(char const *, sal_Int32 len, rtl_TextEncoding) const;
1307 #endif
1308 
1324  sal_Int32 lastIndexOf( const OUString & str ) const SAL_THROW(())
1325  {
1326  return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1327  str.pData->buffer, str.pData->length );
1328  }
1329 
1347  sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const SAL_THROW(())
1348  {
1349  return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1350  str.pData->buffer, str.pData->length );
1351  }
1352 
1358  template< typename T >
1359  typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(())
1360  {
1361  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1363  pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
1364  }
1365 
1385  sal_Int32 lastIndexOfAsciiL(char const * str, sal_Int32 len) const
1386  SAL_THROW(())
1387  {
1389  pData->buffer, pData->length, str, len);
1390  }
1391 
1402  OUString copy( sal_Int32 beginIndex ) const SAL_THROW(())
1403  {
1404  rtl_uString *pNew = 0;
1405  rtl_uString_newFromSubString( &pNew, pData, beginIndex, getLength() - beginIndex );
1406  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1407  }
1408 
1421  OUString copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(())
1422  {
1423  rtl_uString *pNew = 0;
1424  rtl_uString_newFromSubString( &pNew, pData, beginIndex, count );
1425  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1426  }
1427 
1436  SAL_WARN_UNUSED_RESULT OUString concat( const OUString & str ) const SAL_THROW(())
1437  {
1438  rtl_uString* pNew = 0;
1439  rtl_uString_newConcat( &pNew, pData, str.pData );
1440  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1441  }
1442 
1443 #ifndef RTL_FAST_STRING
1444  friend OUString operator+( const OUString& rStr1, const OUString& rStr2 ) SAL_THROW(())
1445  {
1446  return rStr1.concat( rStr2 );
1447  }
1448 #endif
1449 
1463  SAL_WARN_UNUSED_RESULT OUString replaceAt( sal_Int32 index, sal_Int32 count, const OUString& newStr ) const SAL_THROW(())
1464  {
1465  rtl_uString* pNew = 0;
1466  rtl_uString_newReplaceStrAt( &pNew, pData, index, count, newStr.pData );
1467  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1468  }
1469 
1483  SAL_WARN_UNUSED_RESULT OUString replace( sal_Unicode oldChar, sal_Unicode newChar ) const SAL_THROW(())
1484  {
1485  rtl_uString* pNew = 0;
1486  rtl_uString_newReplace( &pNew, pData, oldChar, newChar );
1487  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1488  }
1489 
1509  OUString const & from, OUString const & to, sal_Int32 * index = 0) const
1510  {
1511  rtl_uString * s = 0;
1512  sal_Int32 i = 0;
1514  &s, pData, from.pData, to.pData, index == 0 ? &i : index);
1515  return OUString(s, SAL_NO_ACQUIRE);
1516  }
1517 
1536  template< typename T >
1538  sal_Int32 * index = 0) const
1539  {
1540  rtl_uString * s = 0;
1541  sal_Int32 i = 0;
1542  assert( strlen( from ) == internal::ConstCharArrayDetector< T >::size - 1 );
1544  &s, pData, from, internal::ConstCharArrayDetector< T, void >::size - 1, to.pData, index == 0 ? &i : index);
1545  return OUString(s, SAL_NO_ACQUIRE);
1546  }
1547 
1566  template< typename T1, typename T2 >
1568  replaceFirst( T1& from, T2& to, sal_Int32 * index = 0) const
1569  {
1570  rtl_uString * s = 0;
1571  sal_Int32 i = 0;
1572  assert( strlen( from ) == internal::ConstCharArrayDetector< T1 >::size - 1 );
1573  assert( strlen( to ) == internal::ConstCharArrayDetector< T2 >::size - 1 );
1575  &s, pData, from, internal::ConstCharArrayDetector< T1, void >::size - 1, to,
1576  internal::ConstCharArrayDetector< T2, void >::size - 1, index == 0 ? &i : index);
1577  return OUString(s, SAL_NO_ACQUIRE);
1578  }
1579 
1595  OUString replaceAll(OUString const & from, OUString const & to, sal_Int32 fromIndex = 0) const {
1596  rtl_uString * s = 0;
1597  rtl_uString_newReplaceAllFromIndex(&s, pData, from.pData, to.pData, fromIndex);
1598  return OUString(s, SAL_NO_ACQUIRE);
1599  }
1600 
1614  template< typename T >
1615  typename internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const
1616  {
1617  rtl_uString * s = 0;
1618  assert( strlen( from ) == internal::ConstCharArrayDetector< T >::size - 1 );
1620  return OUString(s, SAL_NO_ACQUIRE);
1621  }
1622 
1636  template< typename T1, typename T2 >
1638  replaceAll( T1& from, T2& to ) const
1639  {
1640  rtl_uString * s = 0;
1641  assert( strlen( from ) == internal::ConstCharArrayDetector< T1 >::size - 1 );
1642  assert( strlen( to ) == internal::ConstCharArrayDetector< T2 >::size - 1 );
1646  return OUString(s, SAL_NO_ACQUIRE);
1647  }
1648 
1659  SAL_WARN_UNUSED_RESULT OUString toAsciiLowerCase() const SAL_THROW(())
1660  {
1661  rtl_uString* pNew = 0;
1662  rtl_uString_newToAsciiLowerCase( &pNew, pData );
1663  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1664  }
1665 
1676  SAL_WARN_UNUSED_RESULT OUString toAsciiUpperCase() const SAL_THROW(())
1677  {
1678  rtl_uString* pNew = 0;
1679  rtl_uString_newToAsciiUpperCase( &pNew, pData );
1680  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1681  }
1682 
1695  {
1696  rtl_uString* pNew = 0;
1697  rtl_uString_newTrim( &pNew, pData );
1698  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
1699  }
1700 
1725  OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const SAL_THROW(())
1726  {
1727  rtl_uString * pNew = 0;
1728  index = rtl_uString_getToken( &pNew, pData, token, cTok, index );
1729  return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
1730  }
1731 
1745  OUString getToken(sal_Int32 count, sal_Unicode separator) const {
1746  sal_Int32 n = 0;
1747  return getToken(count, separator, n);
1748  }
1749 
1758  sal_Bool toBoolean() const SAL_THROW(())
1759  {
1760  return rtl_ustr_toBoolean( pData->buffer );
1761  }
1762 
1769  sal_Unicode toChar() const SAL_THROW(())
1770  {
1771  return pData->buffer[0];
1772  }
1773 
1783  sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
1784  {
1785  return rtl_ustr_toInt32( pData->buffer, radix );
1786  }
1787 
1797  sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
1798  {
1799  return rtl_ustr_toInt64( pData->buffer, radix );
1800  }
1801 
1810  float toFloat() const SAL_THROW(())
1811  {
1812  return rtl_ustr_toFloat( pData->buffer );
1813  }
1814 
1823  double toDouble() const SAL_THROW(())
1824  {
1825  return rtl_ustr_toDouble( pData->buffer );
1826  }
1827 
1828 
1844  OUString intern() const
1845  {
1846  rtl_uString * pNew = 0;
1847  rtl_uString_intern( &pNew, pData );
1848  if (pNew == 0) {
1849 #if defined EXCEPTIONS_OFF
1850  abort();
1851 #else
1852  throw std::bad_alloc();
1853 #endif
1854  }
1855  return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
1856  }
1857 
1883  static OUString intern( const sal_Char * value, sal_Int32 length,
1884  rtl_TextEncoding encoding,
1885  sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS,
1886  sal_uInt32 *pInfo = NULL )
1887  {
1888  rtl_uString * pNew = 0;
1889  rtl_uString_internConvert( &pNew, value, length, encoding,
1890  convertFlags, pInfo );
1891  if (pNew == 0) {
1892 #if defined EXCEPTIONS_OFF
1893  abort();
1894 #else
1895  throw std::bad_alloc();
1896 #endif
1897  }
1898  return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
1899  }
1900 
1925  inline bool convertToString(OString * pTarget, rtl_TextEncoding nEncoding,
1926  sal_uInt32 nFlags) const
1927  {
1928  return rtl_convertUStringToString(&pTarget->pData, pData->buffer,
1929  pData->length, nEncoding, nFlags);
1930  }
1931 
1983  inline sal_uInt32 iterateCodePoints(
1984  sal_Int32 * indexUtf16, sal_Int32 incrementCodePoints = 1) const
1985  {
1987  pData, indexUtf16, incrementCodePoints);
1988  }
1989 
2000  static OUString valueOf( sal_Bool b ) SAL_THROW(())
2001  {
2003  rtl_uString* pNewData = 0;
2004  rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfBoolean( aBuf, b ) );
2005  return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
2006  }
2007 
2014  static OUString valueOf( sal_Unicode c ) SAL_THROW(())
2015  {
2016  return OUString( &c, 1 );
2017  }
2018 
2028  static OUString valueOf( sal_Int32 i, sal_Int16 radix = 10 ) SAL_THROW(())
2029  {
2031  rtl_uString* pNewData = 0;
2032  rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfInt32( aBuf, i, radix ) );
2033  return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
2034  }
2035 
2045  static OUString valueOf( sal_Int64 ll, sal_Int16 radix = 10 ) SAL_THROW(())
2046  {
2048  rtl_uString* pNewData = 0;
2049  rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfInt64( aBuf, ll, radix ) );
2050  return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
2051  }
2052 
2061  static OUString valueOf( float f ) SAL_THROW(())
2062  {
2064  rtl_uString* pNewData = 0;
2065  rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfFloat( aBuf, f ) );
2066  return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
2067  }
2068 
2077  static OUString valueOf( double d ) SAL_THROW(())
2078  {
2080  rtl_uString* pNewData = 0;
2081  rtl_uString_newFromStr_WithLength( &pNewData, aBuf, rtl_ustr_valueOfDouble( aBuf, d ) );
2082  return OUString( pNewData, (DO_NOT_ACQUIRE*)0 );
2083  }
2084 
2100  static OUString createFromAscii( const sal_Char * value ) SAL_THROW(())
2101  {
2102  rtl_uString* pNew = 0;
2103  rtl_uString_newFromAscii( &pNew, value );
2104  return OUString( pNew, (DO_NOT_ACQUIRE*)0 );
2105  }
2106 
2107  template< typename T1, typename T2 >
2108  friend struct OUStringConcat;
2109 };
2110 
2111 /* ======================================================================= */
2112 
2113 #ifdef RTL_FAST_STRING
2114 
2123 {
2124  template< int N >
2125  OUStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) { assert( strlen( str ) == N - 1 ); }
2126  int size;
2127  const char* data;
2128 };
2129 
2130 template<>
2131 struct ToStringHelper< OUString >
2132  {
2133  static int length( const OUString& s ) { return s.getLength(); }
2134  static sal_Unicode* addData( sal_Unicode* buffer, const OUString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
2135  static const bool allowOStringConcat = false;
2136  static const bool allowOUStringConcat = true;
2137  };
2138 
2139 template<>
2140 struct ToStringHelper< OUStringLiteral >
2141  {
2142  static int length( const OUStringLiteral& str ) { return str.size; }
2143  static sal_Unicode* addData( sal_Unicode* buffer, const OUStringLiteral& str ) { return addDataLiteral( buffer, str.data, str.size ); }
2144  static const bool allowOStringConcat = false;
2145  static const bool allowOUStringConcat = true;
2146  };
2147 
2148 template< typename charT, typename traits, typename T1, typename T2 >
2149 inline std::basic_ostream<charT, traits> & operator <<(
2150  std::basic_ostream<charT, traits> & stream, const OUStringConcat< T1, T2 >& concat)
2151 {
2152  return stream << OUString( concat );
2153 }
2154 #else
2155 // non-RTL_FAST_CODE needs this to compile
2157 #endif
2158 
2159 } /* Namespace */
2160 
2161 #ifdef RTL_STRING_UNITTEST
2162 namespace rtl
2163 {
2164 typedef rtlunittest::OUString OUString;
2165 }
2166 #endif
2167 
2168 namespace rtl
2169 {
2170 
2177 {
2187  size_t operator()(const OUString& rString) const
2188  { return (size_t)rString.hashCode(); }
2189 };
2190 
2191 /* ======================================================================= */
2192 
2210 inline OUString OStringToOUString( const OString & rStr,
2211  rtl_TextEncoding encoding,
2212  sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS )
2213 {
2214  return OUString( rStr.getStr(), rStr.getLength(), encoding, convertFlags );
2215 }
2216 
2234 inline OString OUStringToOString( const OUString & rUnicode,
2235  rtl_TextEncoding encoding,
2236  sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
2237 {
2238  return OString( rUnicode.getStr(), rUnicode.getLength(), encoding, convertFlags );
2239 }
2240 
2241 /* ======================================================================= */
2242 
2243 } /* Namespace */
2244 
2245 #ifdef RTL_STRING_UNITTEST
2246 #define rtl rtlunittest
2247 #endif
2248 namespace rtl
2249 {
2250 #ifdef RTL_STRING_UNITTEST
2251 #undef rtl
2252 #endif
2253 
2262 template< typename charT, typename traits >
2263 inline std::basic_ostream<charT, traits> & operator <<(
2264  std::basic_ostream<charT, traits> & stream, OUString const & string)
2265 {
2266  return stream <<
2268  // best effort; potentially loses data due to conversion failures
2269  // (stray surrogate halves) and embedded null characters
2270 }
2271 
2272 } // namespace
2273 
2274 // RTL_USING is defined by gbuild for all modules except those with stable public API
2275 // (as listed in ure/source/README). It allows to use classes like OUString without
2276 // having to explicitly refer to the rtl namespace, which is kind of superfluous
2277 // given that OUString itself is namespaced by its OU prefix.
2278 #ifdef RTL_USING
2279 using ::rtl::OUString;
2280 using ::rtl::OUStringHash;
2284 #endif
2285 
2286 #endif /* _RTL_USTRING_HXX */
2287 
2288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */