LibreOffice
LibreOffice 4.1 SDK C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
string.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_STRING_HXX_
21 #define _RTL_STRING_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/textenc.h>
31 #include <rtl/string.h>
32 #include <rtl/stringutils.hxx>
33 
34 #ifdef RTL_FAST_STRING
35 #include <rtl/stringconcat.hxx>
36 #endif
37 
38 #include "sal/log.hxx"
39 
40 #if !defined EXCEPTIONS_OFF
41 #include <new>
42 #endif
43 
44 // The unittest uses slightly different code to help check that the proper
45 // calls are made. The class is put into a different namespace to make
46 // sure the compiler generates a different (if generating also non-inline)
47 // copy of the function and does not merge them together. The class
48 // is "brought" into the proper rtl namespace by a typedef below.
49 #ifdef RTL_STRING_UNITTEST
50 #define rtl rtlunittest
51 #endif
52 
53 namespace rtl
54 {
55 
56 #ifdef RTL_STRING_UNITTEST
57 #undef rtl
58 // helper macro to make functions appear more readable
59 #define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
60 #else
61 #define RTL_STRING_CONST_FUNCTION
62 #endif
63 
64 /* ======================================================================= */
65 
91 {
92 public:
94  rtl_String * pData;
96 
97 private:
98  class DO_NOT_ACQUIRE;
99 
100  OString( rtl_String * value, SAL_UNUSED_PARAMETER DO_NOT_ACQUIRE * )
101  {
102  pData = value;
103  }
104 
105 public:
110  {
111  pData = 0;
112  rtl_string_new( &pData );
113  }
114 
120  OString( const OString & str ) SAL_THROW(())
121  {
122  pData = str.pData;
123  rtl_string_acquire( pData );
124  }
125 
131  OString( rtl_String * str ) SAL_THROW(())
132  {
133  pData = str;
134  rtl_string_acquire( pData );
135  }
136 
144  inline OString( rtl_String * str, __sal_NoAcquire ) SAL_THROW(())
145  {
146  pData = str;
147  }
148 
154  explicit OString( sal_Char value ) SAL_THROW(())
155  : pData (0)
156  {
157  rtl_string_newFromStr_WithLength( &pData, &value, 1 );
158  }
159 
168  template< typename T >
170  {
171  pData = 0;
172  rtl_string_newFromStr( &pData, value );
173  }
174 
175  template< typename T >
177  {
178  pData = 0;
179  rtl_string_newFromStr( &pData, value );
180  }
181 
192  template< typename T >
194  {
195  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
196  pData = 0;
197  if( internal::ConstCharArrayDetector< T, void >::size - 1 == 0 ) // empty string
198  rtl_string_new( &pData );
199  else
201 #ifdef RTL_STRING_UNITTEST
202  rtl_string_unittest_const_literal = true;
203 #endif
204  }
205 
214  OString( const sal_Char * value, sal_Int32 length ) SAL_THROW(())
215  {
216  pData = 0;
217  rtl_string_newFromStr_WithLength( &pData, value, length );
218  }
219 
234  OString( const sal_Unicode * value, sal_Int32 length,
235  rtl_TextEncoding encoding,
236  sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
237  {
238  pData = 0;
239  rtl_uString2String( &pData, value, length, encoding, convertFlags );
240  if (pData == 0) {
241 #if defined EXCEPTIONS_OFF
242  abort();
243 #else
244  throw std::bad_alloc();
245 #endif
246  }
247  }
248 
249 #ifdef RTL_FAST_STRING
250 
254  template< typename T1, typename T2 >
255  OString( const OStringConcat< T1, T2 >& c )
256  {
257  const sal_Int32 l = c.length();
258  pData = rtl_string_alloc( l );
259  if (l != 0)
260  {
261  char* end = c.addData( pData->buffer );
262  pData->length = end - pData->buffer;
263  *end = '\0';
264  }
265  }
266 #endif
267 
272  {
273  rtl_string_release( pData );
274  }
275 
281  OString & operator=( const OString & str ) SAL_THROW(())
282  {
283  rtl_string_assign( &pData, str.pData );
284  return *this;
285  }
286 
292  template< typename T >
294  {
296  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
297  if( internal::ConstCharArrayDetector< T, void >::size - 1 == 0 ) // empty string
298  rtl_string_new( &pData );
299  else
301  return *this;
302  }
303 
309  OString & operator+=( const OString & str ) SAL_THROW(())
310  {
311  rtl_string_newConcat( &pData, pData, str.pData );
312  return *this;
313  }
314 
315 #ifdef RTL_FAST_STRING
316 
320  template< typename T1, typename T2 >
321  OString& operator+=( const OStringConcat< T1, T2 >& c )
322  {
323  const int l = c.length();
324  if( l == 0 )
325  return *this;
326  rtl_string_ensureCapacity( &pData, pData->length + l );
327  char* end = c.addData( pData->buffer + pData->length );
328  *end = '\0';
329  pData->length = end - pData->buffer;
330  return *this;
331  }
332 #endif
333 
341  sal_Int32 getLength() const SAL_THROW(()) { return pData->length; }
342 
351  bool isEmpty() const SAL_THROW(())
352  {
353  return pData->length == 0;
354  }
355 
367  const sal_Char * getStr() const SAL_THROW(()) { return pData->buffer; }
368 
378  sal_Char operator [](sal_Int32 index) const {
379  assert(index >= 0 && index <= getLength());
380  //TODO: should really check for < getLength(), but there is quite
381  // some clever code out there that violates this function's
382  // documented precondition and relies on s[s.getLength()] == 0 and
383  // that would need to be fixed first
384  return getStr()[index];
385  }
386 
399  sal_Int32 compareTo( const OString & str ) const SAL_THROW(())
400  {
401  return rtl_str_compare_WithLength( pData->buffer, pData->length,
402  str.pData->buffer, str.pData->length );
403  }
404 
418  sal_Int32 compareTo( const OString & rObj, sal_Int32 maxLength ) const SAL_THROW(())
419  {
420  return rtl_str_shortenedCompare_WithLength( pData->buffer, pData->length,
421  rObj.pData->buffer, rObj.pData->length, maxLength );
422  }
423 
436  sal_Int32 reverseCompareTo( const OString & str ) const SAL_THROW(())
437  {
438  return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
439  str.pData->buffer, str.pData->length );
440  }
441 
453  sal_Bool equals( const OString & str ) const SAL_THROW(())
454  {
455  if ( pData->length != str.pData->length )
456  return sal_False;
457  if ( pData == str.pData )
458  return sal_True;
459  return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
460  str.pData->buffer, str.pData->length ) == 0;
461  }
462 
478  sal_Bool equalsL( const sal_Char* value, sal_Int32 length ) const SAL_THROW(())
479  {
480  if ( pData->length != length )
481  return sal_False;
482 
483  return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
484  value, length ) == 0;
485  }
486 
501  sal_Bool equalsIgnoreAsciiCase( const OString & str ) const SAL_THROW(())
502  {
503  if ( pData->length != str.pData->length )
504  return sal_False;
505  if ( pData == str.pData )
506  return sal_True;
507  return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
508  str.pData->buffer, str.pData->length ) == 0;
509  }
510 
532  template< typename T >
533  typename internal::CharPtrDetector< T, bool >::Type equalsIgnoreAsciiCase( const T& asciiStr ) const SAL_THROW(())
534  {
535  return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
536  }
537 
538  template< typename T >
539  typename internal::NonConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& asciiStr ) const SAL_THROW(())
540  {
541  return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
542  }
543 
549  template< typename T >
550  typename internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(())
551  {
553  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
554  if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 )
555  return false;
556  return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
558  }
559 
579  sal_Bool equalsIgnoreAsciiCaseL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
580  {
581  if ( pData->length != asciiStrLength )
582  return sal_False;
583 
584  return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
585  asciiStr, asciiStrLength ) == 0;
586  }
587 
603  sal_Bool match( const OString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
604  {
605  return rtl_str_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
606  str.pData->buffer, str.pData->length, str.pData->length ) == 0;
607  }
608 
614  template< typename T >
615  typename internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
616  {
618  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
620  pData->buffer + fromIndex, pData->length - fromIndex,
622  }
623 
640  bool matchL(
641  char const * str, sal_Int32 strLength, sal_Int32 fromIndex = 0)
642  const
643  {
645  pData->buffer + fromIndex, pData->length - fromIndex,
646  str, strLength, strLength) == 0;
647  }
648 
649  // This overload is left undefined, to detect calls of matchL that
650  // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
651  // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
652  // platforms):
653 #if SAL_TYPES_SIZEOFLONG == 8
654  void matchL(char const *, sal_Int32, rtl_TextEncoding) const;
655 #endif
656 
675  sal_Bool matchIgnoreAsciiCase( const OString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
676  {
677  return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
678  str.pData->buffer, str.pData->length,
679  str.pData->length ) == 0;
680  }
681 
687  template< typename T >
688  typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const
689  {
691  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
692  return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
694  }
695 
706  bool startsWith(OString const & str) const {
707  return match(str, 0);
708  }
709 
715  template< typename T >
716  typename internal::ConstCharArrayDetector< T, bool >::Type startsWith( T& literal ) const
717  {
719  return match(literal, 0);
720  }
721 
732  bool endsWith(OString const & str) const {
733  return str.getLength() <= getLength()
734  && match(str, getLength() - str.getLength());
735  }
736 
742  template< typename T >
743  typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const
744  {
746  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
747  return internal::ConstCharArrayDetector< T, void >::size - 1 <= getLength()
748  && match(literal, getLength() - ( internal::ConstCharArrayDetector< T, void >::size - 1 ));
749  }
750 
764  bool endsWithL(char const * str, sal_Int32 strLength) const {
765  return strLength <= getLength()
766  && matchL(str, strLength, getLength() - strLength);
767  }
768 
769  friend sal_Bool operator == ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
770  { return rStr1.equals(rStr2); }
771  friend sal_Bool operator != ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
772  { return !(operator == ( rStr1, rStr2 )); }
773  friend sal_Bool operator < ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
774  { return rStr1.compareTo( rStr2 ) < 0; }
775  friend sal_Bool operator > ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
776  { return rStr1.compareTo( rStr2 ) > 0; }
777  friend sal_Bool operator <= ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
778  { return rStr1.compareTo( rStr2 ) <= 0; }
779  friend sal_Bool operator >= ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
780  { return rStr1.compareTo( rStr2 ) >= 0; }
781 
782  template< typename T >
783  friend typename internal::CharPtrDetector< T, bool >::Type operator==( const OString& rStr1, const T& value ) SAL_THROW(())
784  {
785  return rStr1.compareTo( value ) == 0;
786  }
787 
788  template< typename T >
790  {
791  return rStr1.compareTo( value ) == 0;
792  }
793 
794  template< typename T >
795  friend typename internal::CharPtrDetector< T, bool >::Type operator==( const T& value, const OString& rStr2 ) SAL_THROW(())
796  {
797  return rStr2.compareTo( value ) == 0;
798  }
799 
800  template< typename T >
802  {
803  return rStr2.compareTo( value ) == 0;
804  }
805 
811  template< typename T >
812  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OString& rStr, T& literal ) SAL_THROW(())
813  {
815  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
816  return rStr.getLength() == internal::ConstCharArrayDetector< T, void >::size - 1
817  && rtl_str_compare_WithLength( rStr.pData->buffer, rStr.pData->length, literal,
819  }
820 
826  template< typename T >
827  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OString& rStr ) SAL_THROW(())
828  {
830  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
831  return rStr.getLength() == internal::ConstCharArrayDetector< T, void >::size - 1
832  && rtl_str_compare_WithLength( rStr.pData->buffer, rStr.pData->length, literal,
834  }
835 
836  template< typename T >
837  friend typename internal::CharPtrDetector< T, bool >::Type operator!=( const OString& rStr1, const T& value ) SAL_THROW(())
838  {
839  return !(operator == ( rStr1, value ));
840  }
841 
842  template< typename T >
844  {
845  return !(operator == ( rStr1, value ));
846  }
847 
848  template< typename T >
849  friend typename internal::CharPtrDetector< T, bool >::Type operator!=( const T& value, const OString& rStr2 ) SAL_THROW(())
850  {
851  return !(operator == ( value, rStr2 ));
852  }
853 
854  template< typename T >
856  {
857  return !(operator == ( value, rStr2 ));
858  }
859 
865  template< typename T >
866  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OString& rStr, T& literal ) SAL_THROW(())
867  {
868  return !( rStr == literal );
869  }
870 
876  template< typename T >
877  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OString& rStr ) SAL_THROW(())
878  {
879  return !( literal == rStr );
880  }
881 
889  sal_Int32 hashCode() const SAL_THROW(())
890  {
891  return rtl_str_hashCode_WithLength( pData->buffer, pData->length );
892  }
893 
907  sal_Int32 indexOf( sal_Char ch, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
908  {
909  sal_Int32 ret = rtl_str_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
910  return (ret < 0 ? ret : ret+fromIndex);
911  }
912 
922  sal_Int32 lastIndexOf( sal_Char ch ) const SAL_THROW(())
923  {
924  return rtl_str_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
925  }
926 
939  sal_Int32 lastIndexOf( sal_Char ch, sal_Int32 fromIndex ) const SAL_THROW(())
940  {
941  return rtl_str_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
942  }
943 
959  sal_Int32 indexOf( const OString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
960  {
961  sal_Int32 ret = rtl_str_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
962  str.pData->buffer, str.pData->length );
963  return (ret < 0 ? ret : ret+fromIndex);
964  }
965 
971  template< typename T >
972  typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
973  {
975  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
976  sal_Int32 n = rtl_str_indexOfStr_WithLength(
977  pData->buffer + fromIndex, pData->length - fromIndex, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
978  return n < 0 ? n : n + fromIndex;
979  }
980 
999  sal_Int32 indexOfL(char const * str, sal_Int32 len, sal_Int32 fromIndex = 0)
1000  const SAL_THROW(())
1001  {
1002  sal_Int32 n = rtl_str_indexOfStr_WithLength(
1003  pData->buffer + fromIndex, pData->length - fromIndex, str, len);
1004  return n < 0 ? n : n + fromIndex;
1005  }
1006 
1007  // This overload is left undefined, to detect calls of indexOfL that
1008  // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
1009  // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
1010  // platforms):
1011 #if SAL_TYPES_SIZEOFLONG == 8
1012  void indexOfL(char const *, sal_Int32, rtl_TextEncoding) const;
1013 #endif
1014 
1030  sal_Int32 lastIndexOf( const OString & str ) const SAL_THROW(())
1031  {
1032  return rtl_str_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1033  str.pData->buffer, str.pData->length );
1034  }
1035 
1053  sal_Int32 lastIndexOf( const OString & str, sal_Int32 fromIndex ) const SAL_THROW(())
1054  {
1055  return rtl_str_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1056  str.pData->buffer, str.pData->length );
1057  }
1058 
1069  SAL_WARN_UNUSED_RESULT OString copy( sal_Int32 beginIndex ) const SAL_THROW(())
1070  {
1071  rtl_String *pNew = 0;
1072  rtl_string_newFromSubString( &pNew, pData, beginIndex, getLength() - beginIndex );
1073  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1074  }
1075 
1088  SAL_WARN_UNUSED_RESULT OString copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(())
1089  {
1090  rtl_String *pNew = 0;
1091  rtl_string_newFromSubString( &pNew, pData, beginIndex, count );
1092  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1093  }
1094 
1103  SAL_WARN_UNUSED_RESULT OString concat( const OString & str ) const SAL_THROW(())
1104  {
1105  rtl_String* pNew = 0;
1106  rtl_string_newConcat( &pNew, pData, str.pData );
1107  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1108  }
1109 
1110 #ifndef RTL_FAST_STRING
1111  friend OString operator+( const OString & str1, const OString & str2 ) SAL_THROW(())
1112  {
1113  return str1.concat( str2 );
1114  }
1115 #endif
1116 
1130  SAL_WARN_UNUSED_RESULT OString replaceAt( sal_Int32 index, sal_Int32 count, const OString& newStr ) const SAL_THROW(())
1131  {
1132  rtl_String* pNew = 0;
1133  rtl_string_newReplaceStrAt( &pNew, pData, index, count, newStr.pData );
1134  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1135  }
1136 
1150  SAL_WARN_UNUSED_RESULT OString replace( sal_Char oldChar, sal_Char newChar ) const SAL_THROW(())
1151  {
1152  rtl_String* pNew = 0;
1153  rtl_string_newReplace( &pNew, pData, oldChar, newChar );
1154  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1155  }
1156 
1176  OString const & from, OString const & to, sal_Int32 * index = 0) const
1177  {
1178  rtl_String * s = 0;
1179  sal_Int32 i = 0;
1181  &s, pData, from.pData->buffer, from.pData->length,
1182  to.pData->buffer, to.pData->length, index == 0 ? &i : index);
1183  return OString(s, SAL_NO_ACQUIRE);
1184  }
1185 
1199  SAL_WARN_UNUSED_RESULT OString replaceAll(OString const & from, OString const & to) const {
1200  rtl_String * s = 0;
1202  &s, pData, from.pData->buffer, from.pData->length,
1203  to.pData->buffer, to.pData->length);
1204  return OString(s, SAL_NO_ACQUIRE);
1205  }
1206 
1217  SAL_WARN_UNUSED_RESULT OString toAsciiLowerCase() const SAL_THROW(())
1218  {
1219  rtl_String* pNew = 0;
1220  rtl_string_newToAsciiLowerCase( &pNew, pData );
1221  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1222  }
1223 
1234  SAL_WARN_UNUSED_RESULT OString toAsciiUpperCase() const SAL_THROW(())
1235  {
1236  rtl_String* pNew = 0;
1237  rtl_string_newToAsciiUpperCase( &pNew, pData );
1238  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1239  }
1240 
1253  {
1254  rtl_String* pNew = 0;
1255  rtl_string_newTrim( &pNew, pData );
1256  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1257  }
1258 
1283  OString getToken( sal_Int32 token, sal_Char cTok, sal_Int32& index ) const SAL_THROW(())
1284  {
1285  rtl_String * pNew = 0;
1286  index = rtl_string_getToken( &pNew, pData, token, cTok, index );
1287  return OString( pNew, (DO_NOT_ACQUIRE *)0 );
1288  }
1289 
1303  OString getToken(sal_Int32 count, char separator) const {
1304  sal_Int32 n = 0;
1305  return getToken(count, separator, n);
1306  }
1307 
1316  sal_Bool toBoolean() const SAL_THROW(())
1317  {
1318  return rtl_str_toBoolean( pData->buffer );
1319  }
1320 
1327  sal_Char toChar() const SAL_THROW(())
1328  {
1329  return pData->buffer[0];
1330  }
1331 
1342  sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
1343  {
1344  return rtl_str_toInt32( pData->buffer, radix );
1345  }
1346 
1357  sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
1358  {
1359  return rtl_str_toInt64( pData->buffer, radix );
1360  }
1361 
1374  sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
1375  {
1376  return rtl_str_toUInt64( pData->buffer, radix );
1377  }
1378 
1387  float toFloat() const SAL_THROW(())
1388  {
1389  return rtl_str_toFloat( pData->buffer );
1390  }
1391 
1400  double toDouble() const SAL_THROW(())
1401  {
1402  return rtl_str_toDouble( pData->buffer );
1403  }
1404 
1415  static OString number( int i, sal_Int16 radix = 10 )
1416  {
1417  return number( static_cast< long long >( i ), radix );
1418  }
1421  static OString number( unsigned int i, sal_Int16 radix = 10 )
1422  {
1423  return number( static_cast< unsigned long long >( i ), radix );
1424  }
1427  static OString number( long i, sal_Int16 radix = 10 )
1428  {
1429  return number( static_cast< long long >( i ), radix );
1430  }
1433  static OString number( unsigned long i, sal_Int16 radix = 10 )
1434  {
1435  return number( static_cast< unsigned long long >( i ), radix );
1436  }
1439  static OString number( long long ll, sal_Int16 radix = 10 )
1440  {
1442  rtl_String* pNewData = 0;
1443  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfInt64( aBuf, ll, radix ) );
1444  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1445  }
1448  static OString number( unsigned long long ll, sal_Int16 radix = 10 )
1449  {
1451  rtl_String* pNewData = 0;
1452  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfUInt64( aBuf, ll, radix ) );
1453  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1454  }
1455 
1465  static OString number( float f )
1466  {
1468  rtl_String* pNewData = 0;
1469  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfFloat( aBuf, f ) );
1470  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1471  }
1472 
1482  static OString number( double d )
1483  {
1485  rtl_String* pNewData = 0;
1486  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfDouble( aBuf, d ) );
1487  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1488  }
1489 
1501  SAL_DEPRECATED_INTERNAL("use boolean()") static OString valueOf( sal_Bool b ) SAL_THROW(())
1502  {
1503  return boolean(b);
1504  }
1505 
1517  static OString boolean( bool b ) SAL_THROW(())
1518  {
1520  rtl_String* pNewData = 0;
1521  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfBoolean( aBuf, b ) );
1522  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1523  }
1524 
1532  SAL_DEPRECATED_INTERNAL("convert to OString or use directly") static OString valueOf( sal_Char c ) SAL_THROW(())
1533  {
1534  return OString( &c, 1 );
1535  }
1536 
1547  SAL_DEPRECATED_INTERNAL("use number()") static OString valueOf( sal_Int32 i, sal_Int16 radix = 10 ) SAL_THROW(())
1548  {
1549  return number( i, radix );
1550  }
1551 
1562  SAL_DEPRECATED_INTERNAL("use number()") static OString valueOf( sal_Int64 ll, sal_Int16 radix = 10 ) SAL_THROW(())
1563  {
1564  return number( ll, radix );
1565  }
1566 
1576  SAL_DEPRECATED_INTERNAL("use number()") static OString valueOf( float f ) SAL_THROW(())
1577  {
1578  return number(f);
1579  }
1580 
1590  SAL_DEPRECATED_INTERNAL("use number()") static OString valueOf( double d ) SAL_THROW(())
1591  {
1592  return number(d);
1593  }
1594 
1595 };
1596 
1597 /* ======================================================================= */
1598 
1599 #ifdef RTL_FAST_STRING
1600 
1609 {
1610  template< int N >
1611  OStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) { assert( strlen( str ) == N - 1 ); }
1612  int size;
1613  const char* data;
1614 };
1615 
1619 template<>
1620 struct ToStringHelper< OString >
1621  {
1622  static int length( const OString& s ) { return s.getLength(); }
1623  static char* addData( char* buffer, const OString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
1624  static const bool allowOStringConcat = true;
1625  static const bool allowOUStringConcat = false;
1626  };
1627 
1631 template<>
1632 struct ToStringHelper< OStringLiteral >
1633  {
1634  static int length( const OStringLiteral& str ) { return str.size; }
1635  static char* addData( char* buffer, const OStringLiteral& str ) { return addDataHelper( buffer, str.data, str.size ); }
1636  static const bool allowOStringConcat = true;
1637  static const bool allowOUStringConcat = false;
1638  };
1639 
1643 template< typename charT, typename traits, typename T1, typename T2 >
1644 inline std::basic_ostream<charT, traits> & operator <<(
1645  std::basic_ostream<charT, traits> & stream, const OStringConcat< T1, T2 >& concat)
1646 {
1647  return stream << OString( concat );
1648 }
1649 #else
1650 // non-RTL_FAST_CODE needs this to compile
1652 #endif
1653 
1654 
1661 {
1671  size_t operator()( const OString& rString ) const
1672  { return (size_t)rString.hashCode(); }
1673 };
1674 
1677 {
1678  bool operator()( const char* p1, const char* p2) const
1679  { return rtl_str_compare(p1, p2) == 0; }
1680 };
1681 
1684 {
1685  size_t operator()(const char* p) const
1686  { return rtl_str_hashCode(p); }
1687 };
1688 
1689 /* ======================================================================= */
1690 
1697 template< typename charT, typename traits > std::basic_ostream<charT, traits> &
1699  std::basic_ostream<charT, traits> & stream, OString const & string)
1700 {
1701  return stream << string.getStr();
1702  // best effort; potentially loses data due to embedded null characters
1703 }
1704 
1705 } /* Namespace */
1706 
1707 #ifdef RTL_STRING_UNITTEST
1708 namespace rtl
1709 {
1710 typedef rtlunittest::OString OString;
1711 }
1712 #undef RTL_STRING_CONST_FUNCTION
1713 #endif
1714 
1715 #ifdef RTL_USING
1716 using ::rtl::OString;
1717 using ::rtl::OStringHash;
1719 #endif
1720 
1721 #endif /* _RTL_STRING_HXX_ */
1722 
1723 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */