My Project
UDK 3.2.7 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 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
169  // Old gcc can try to convert anonymous enums to OString and give compile error.
170  // So there's no special-cased handling of string literals.
171  // These are inline functions and technically both variants should work
172  // the same in practice, so there should be no compatibility problem.
173  OString( const sal_Char * value ) SAL_THROW(())
174  {
175  pData = 0;
176  rtl_string_newFromStr( &pData, value );
177  }
178 #else
179  template< typename T >
181  {
182  pData = 0;
183  rtl_string_newFromStr( &pData, value );
184  }
185 
186  template< typename T >
188  {
189  pData = 0;
190  rtl_string_newFromStr( &pData, value );
191  }
192 
203  template< typename T >
205  {
206  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
207  pData = 0;
209 #ifdef RTL_STRING_UNITTEST
210  rtl_string_unittest_const_literal = true;
211 #endif
212  }
213 
214 #endif // HAVE_SFINAE_ANONYMOUS_BROKEN
215 
224  OString( const sal_Char * value, sal_Int32 length ) SAL_THROW(())
225  {
226  pData = 0;
227  rtl_string_newFromStr_WithLength( &pData, value, length );
228  }
229 
244  OString( const sal_Unicode * value, sal_Int32 length,
245  rtl_TextEncoding encoding,
246  sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
247  {
248  pData = 0;
249  rtl_uString2String( &pData, value, length, encoding, convertFlags );
250  if (pData == 0) {
251 #if defined EXCEPTIONS_OFF
252  abort();
253 #else
254  throw std::bad_alloc();
255 #endif
256  }
257  }
258 
259 #ifdef RTL_FAST_STRING
260  template< typename T1, typename T2 >
261  OString( const OStringConcat< T1, T2 >& c )
262  {
263  const sal_Int32 l = c.length();
264  rtl_String* buffer = NULL;
265  rtl_string_new_WithLength( &buffer, l );
266  if (l != 0)
267  {
268  char* end = c.addData( buffer->buffer );
269  buffer->length = end - buffer->buffer;
270  }
271  pData = buffer;
272  }
273 #endif
274 
279  {
280  rtl_string_release( pData );
281  }
282 
288  OString & operator=( const OString & str ) SAL_THROW(())
289  {
290  rtl_string_assign( &pData, str.pData );
291  return *this;
292  }
293 
299  template< typename T >
301  {
303  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
305  return *this;
306  }
307 
313  OString & operator+=( const OString & str ) SAL_THROW(())
314  {
315  rtl_string_newConcat( &pData, pData, str.pData );
316  return *this;
317  }
318 
327  sal_Int32 getLength() const SAL_THROW(()) { return pData->length; }
328 
337  bool isEmpty() const SAL_THROW(())
338  {
339  return pData->length == 0;
340  }
341 
353  const sal_Char * getStr() const SAL_THROW(()) { return pData->buffer; }
354 
364  sal_Char operator [](sal_Int32 index) const { return getStr()[index]; }
365 
378  sal_Int32 compareTo( const OString & str ) const SAL_THROW(())
379  {
380  return rtl_str_compare_WithLength( pData->buffer, pData->length,
381  str.pData->buffer, str.pData->length );
382  }
383 
397  sal_Int32 compareTo( const OString & rObj, sal_Int32 maxLength ) const SAL_THROW(())
398  {
399  return rtl_str_shortenedCompare_WithLength( pData->buffer, pData->length,
400  rObj.pData->buffer, rObj.pData->length, maxLength );
401  }
402 
415  sal_Int32 reverseCompareTo( const OString & str ) const SAL_THROW(())
416  {
417  return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
418  str.pData->buffer, str.pData->length );
419  }
420 
432  sal_Bool equals( const OString & str ) const SAL_THROW(())
433  {
434  if ( pData->length != str.pData->length )
435  return sal_False;
436  if ( pData == str.pData )
437  return sal_True;
438  return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
439  str.pData->buffer, str.pData->length ) == 0;
440  }
441 
457  sal_Bool equalsL( const sal_Char* value, sal_Int32 length ) const SAL_THROW(())
458  {
459  if ( pData->length != length )
460  return sal_False;
461 
462  return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
463  value, length ) == 0;
464  }
465 
480  sal_Bool equalsIgnoreAsciiCase( const OString & str ) const SAL_THROW(())
481  {
482  if ( pData->length != str.pData->length )
483  return sal_False;
484  if ( pData == str.pData )
485  return sal_True;
486  return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
487  str.pData->buffer, str.pData->length ) == 0;
488  }
489 
511 #ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
512  sal_Bool equalsIgnoreAsciiCase( const sal_Char * asciiStr ) const SAL_THROW(())
513  {
514  return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
515  }
516 #else
517  template< typename T >
518  typename internal::CharPtrDetector< T, bool >::Type equalsIgnoreAsciiCase( const T& asciiStr ) const SAL_THROW(())
519  {
520  return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
521  }
522 
523  template< typename T >
524  typename internal::NonConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& asciiStr ) const SAL_THROW(())
525  {
526  return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
527  }
528 
534  template< typename T >
535  typename internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const SAL_THROW(())
536  {
538  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
539  if ( pData->length != internal::ConstCharArrayDetector< T, void >::size - 1 )
540  return false;
541  return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
543  }
544 #endif
545 
565  sal_Bool equalsIgnoreAsciiCaseL( const sal_Char * asciiStr, sal_Int32 asciiStrLength ) const SAL_THROW(())
566  {
567  if ( pData->length != asciiStrLength )
568  return sal_False;
569 
570  return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
571  asciiStr, asciiStrLength ) == 0;
572  }
573 
589  sal_Bool match( const OString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
590  {
591  return rtl_str_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
592  str.pData->buffer, str.pData->length, str.pData->length ) == 0;
593  }
594 
600  template< typename T >
601  typename internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
602  {
604  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
606  pData->buffer + fromIndex, pData->length - fromIndex,
608  }
609 
626  bool matchL(
627  char const * str, sal_Int32 strLength, sal_Int32 fromIndex = 0)
628  const
629  {
631  pData->buffer + fromIndex, pData->length - fromIndex,
632  str, strLength, strLength) == 0;
633  }
634 
635  // This overload is left undefined, to detect calls of matchL that
636  // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
637  // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
638  // platforms):
639 #if SAL_TYPES_SIZEOFLONG == 8
640  void matchL(char const *, sal_Int32, rtl_TextEncoding) const;
641 #endif
642 
661  sal_Bool matchIgnoreAsciiCase( const OString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
662  {
663  return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
664  str.pData->buffer, str.pData->length,
665  str.pData->length ) == 0;
666  }
667 
673  template< typename T >
674  typename internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const
675  {
677  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
678  return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
680  }
681 
692  bool startsWith(OString const & str) const {
693  return match(str, 0);
694  }
695 
701  template< typename T >
702  typename internal::ConstCharArrayDetector< T, bool >::Type startsWith( T& literal ) const
703  {
705  return match(literal, 0);
706  }
707 
718  bool endsWith(OString const & str) const {
719  return str.getLength() <= getLength()
720  && match(str, getLength() - str.getLength());
721  }
722 
728  template< typename T >
729  typename internal::ConstCharArrayDetector< T, bool >::Type endsWith( T& literal ) const
730  {
732  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
733  return internal::ConstCharArrayDetector< T, void >::size - 1 <= getLength()
734  && match(literal, getLength() - ( internal::ConstCharArrayDetector< T, void >::size - 1 ));
735  }
736 
750  bool endsWithL(char const * str, sal_Int32 strLength) const {
751  return strLength <= getLength()
752  && matchL(str, strLength, getLength() - strLength);
753  }
754 
755  friend sal_Bool operator == ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
756  { return rStr1.equals(rStr2); }
757  friend sal_Bool operator != ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
758  { return !(operator == ( rStr1, rStr2 )); }
759  friend sal_Bool operator < ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
760  { return rStr1.compareTo( rStr2 ) < 0; }
761  friend sal_Bool operator > ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
762  { return rStr1.compareTo( rStr2 ) > 0; }
763  friend sal_Bool operator <= ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
764  { return rStr1.compareTo( rStr2 ) <= 0; }
765  friend sal_Bool operator >= ( const OString& rStr1, const OString& rStr2 ) SAL_THROW(())
766  { return rStr1.compareTo( rStr2 ) >= 0; }
767 
768  template< typename T >
769  friend typename internal::CharPtrDetector< T, bool >::Type operator==( const OString& rStr1, const T& value ) SAL_THROW(())
770  {
771  return rStr1.compareTo( value ) == 0;
772  }
773 
774  template< typename T >
776  {
777  return rStr1.compareTo( value ) == 0;
778  }
779 
780  template< typename T >
781  friend typename internal::CharPtrDetector< T, bool >::Type operator==( const T& value, const OString& rStr2 ) SAL_THROW(())
782  {
783  return rStr2.compareTo( value ) == 0;
784  }
785 
786  template< typename T >
788  {
789  return rStr2.compareTo( value ) == 0;
790  }
791 
797  template< typename T >
798  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator==( const OString& rStr, T& literal ) SAL_THROW(())
799  {
801  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
802  return rStr.getLength() == internal::ConstCharArrayDetector< T, void >::size - 1
803  && rtl_str_compare_WithLength( rStr.pData->buffer, rStr.pData->length, literal,
805  }
806 
812  template< typename T >
813  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OString& rStr ) SAL_THROW(())
814  {
816  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
817  return rStr.getLength() == internal::ConstCharArrayDetector< T, void >::size - 1
818  && rtl_str_compare_WithLength( rStr.pData->buffer, rStr.pData->length, literal,
820  }
821 
822  template< typename T >
823  friend typename internal::CharPtrDetector< T, bool >::Type operator!=( const OString& rStr1, const T& value ) SAL_THROW(())
824  {
825  return !(operator == ( rStr1, value ));
826  }
827 
828  template< typename T >
830  {
831  return !(operator == ( rStr1, value ));
832  }
833 
834  template< typename T >
835  friend typename internal::CharPtrDetector< T, bool >::Type operator!=( const T& value, const OString& rStr2 ) SAL_THROW(())
836  {
837  return !(operator == ( value, rStr2 ));
838  }
839 
840  template< typename T >
842  {
843  return !(operator == ( value, rStr2 ));
844  }
845 
851  template< typename T >
852  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OString& rStr, T& literal ) SAL_THROW(())
853  {
854  return !( rStr == literal );
855  }
856 
862  template< typename T >
863  friend typename internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OString& rStr ) SAL_THROW(())
864  {
865  return !( literal == rStr );
866  }
867 
875  sal_Int32 hashCode() const SAL_THROW(())
876  {
877  return rtl_str_hashCode_WithLength( pData->buffer, pData->length );
878  }
879 
893  sal_Int32 indexOf( sal_Char ch, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
894  {
895  sal_Int32 ret = rtl_str_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
896  return (ret < 0 ? ret : ret+fromIndex);
897  }
898 
908  sal_Int32 lastIndexOf( sal_Char ch ) const SAL_THROW(())
909  {
910  return rtl_str_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
911  }
912 
925  sal_Int32 lastIndexOf( sal_Char ch, sal_Int32 fromIndex ) const SAL_THROW(())
926  {
927  return rtl_str_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
928  }
929 
945  sal_Int32 indexOf( const OString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
946  {
947  sal_Int32 ret = rtl_str_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
948  str.pData->buffer, str.pData->length );
949  return (ret < 0 ? ret : ret+fromIndex);
950  }
951 
957  template< typename T >
958  typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
959  {
961  assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
962  sal_Int32 n = rtl_str_indexOfStr_WithLength(
963  pData->buffer + fromIndex, pData->length - fromIndex, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
964  return n < 0 ? n : n + fromIndex;
965  }
966 
985  sal_Int32 indexOfL(char const * str, sal_Int32 len, sal_Int32 fromIndex = 0)
986  const SAL_THROW(())
987  {
988  sal_Int32 n = rtl_str_indexOfStr_WithLength(
989  pData->buffer + fromIndex, pData->length - fromIndex, str, len);
990  return n < 0 ? n : n + fromIndex;
991  }
992 
993  // This overload is left undefined, to detect calls of indexOfL that
994  // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
995  // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
996  // platforms):
997 #if SAL_TYPES_SIZEOFLONG == 8
998  void indexOfL(char const *, sal_Int32, rtl_TextEncoding) const;
999 #endif
1000 
1016  sal_Int32 lastIndexOf( const OString & str ) const SAL_THROW(())
1017  {
1018  return rtl_str_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1019  str.pData->buffer, str.pData->length );
1020  }
1021 
1039  sal_Int32 lastIndexOf( const OString & str, sal_Int32 fromIndex ) const SAL_THROW(())
1040  {
1041  return rtl_str_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1042  str.pData->buffer, str.pData->length );
1043  }
1044 
1055  OString copy( sal_Int32 beginIndex ) const SAL_THROW(())
1056  {
1057  rtl_String *pNew = 0;
1058  rtl_string_newFromSubString( &pNew, pData, beginIndex, getLength() - beginIndex );
1059  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1060  }
1061 
1074  OString copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(())
1075  {
1076  rtl_String *pNew = 0;
1077  rtl_string_newFromSubString( &pNew, pData, beginIndex, count );
1078  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1079  }
1080 
1089  SAL_WARN_UNUSED_RESULT OString concat( const OString & str ) const SAL_THROW(())
1090  {
1091  rtl_String* pNew = 0;
1092  rtl_string_newConcat( &pNew, pData, str.pData );
1093  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1094  }
1095 
1096 #ifndef RTL_FAST_STRING
1097  friend OString operator+( const OString & str1, const OString & str2 ) SAL_THROW(())
1098  {
1099  return str1.concat( str2 );
1100  }
1101 #endif
1102 
1116  SAL_WARN_UNUSED_RESULT OString replaceAt( sal_Int32 index, sal_Int32 count, const OString& newStr ) const SAL_THROW(())
1117  {
1118  rtl_String* pNew = 0;
1119  rtl_string_newReplaceStrAt( &pNew, pData, index, count, newStr.pData );
1120  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1121  }
1122 
1136  SAL_WARN_UNUSED_RESULT OString replace( sal_Char oldChar, sal_Char newChar ) const SAL_THROW(())
1137  {
1138  rtl_String* pNew = 0;
1139  rtl_string_newReplace( &pNew, pData, oldChar, newChar );
1140  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1141  }
1142 
1162  OString const & from, OString const & to, sal_Int32 * index = 0) const
1163  {
1164  rtl_String * s = 0;
1165  sal_Int32 i = 0;
1167  &s, pData, from.pData->buffer, from.pData->length,
1168  to.pData->buffer, to.pData->length, index == 0 ? &i : index);
1169  return OString(s, SAL_NO_ACQUIRE);
1170  }
1171 
1185  SAL_WARN_UNUSED_RESULT OString replaceAll(OString const & from, OString const & to) const {
1186  rtl_String * s = 0;
1188  &s, pData, from.pData->buffer, from.pData->length,
1189  to.pData->buffer, to.pData->length);
1190  return OString(s, SAL_NO_ACQUIRE);
1191  }
1192 
1203  SAL_WARN_UNUSED_RESULT OString toAsciiLowerCase() const SAL_THROW(())
1204  {
1205  rtl_String* pNew = 0;
1206  rtl_string_newToAsciiLowerCase( &pNew, pData );
1207  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1208  }
1209 
1220  SAL_WARN_UNUSED_RESULT OString toAsciiUpperCase() const SAL_THROW(())
1221  {
1222  rtl_String* pNew = 0;
1223  rtl_string_newToAsciiUpperCase( &pNew, pData );
1224  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1225  }
1226 
1239  {
1240  rtl_String* pNew = 0;
1241  rtl_string_newTrim( &pNew, pData );
1242  return OString( pNew, (DO_NOT_ACQUIRE*)0 );
1243  }
1244 
1269  OString getToken( sal_Int32 token, sal_Char cTok, sal_Int32& index ) const SAL_THROW(())
1270  {
1271  rtl_String * pNew = 0;
1272  index = rtl_string_getToken( &pNew, pData, token, cTok, index );
1273  return OString( pNew, (DO_NOT_ACQUIRE *)0 );
1274  }
1275 
1289  OString getToken(sal_Int32 count, char separator) const {
1290  sal_Int32 n = 0;
1291  return getToken(count, separator, n);
1292  }
1293 
1302  sal_Bool toBoolean() const SAL_THROW(())
1303  {
1304  return rtl_str_toBoolean( pData->buffer );
1305  }
1306 
1313  sal_Char toChar() const SAL_THROW(())
1314  {
1315  return pData->buffer[0];
1316  }
1317 
1327  sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
1328  {
1329  return rtl_str_toInt32( pData->buffer, radix );
1330  }
1331 
1341  sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
1342  {
1343  return rtl_str_toInt64( pData->buffer, radix );
1344  }
1345 
1354  float toFloat() const SAL_THROW(())
1355  {
1356  return rtl_str_toFloat( pData->buffer );
1357  }
1358 
1367  double toDouble() const SAL_THROW(())
1368  {
1369  return rtl_str_toDouble( pData->buffer );
1370  }
1371 
1382  static OString valueOf( sal_Bool b ) SAL_THROW(())
1383  {
1385  rtl_String* pNewData = 0;
1386  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfBoolean( aBuf, b ) );
1387  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1388  }
1389 
1396  static OString valueOf( sal_Char c ) SAL_THROW(())
1397  {
1398  return OString( &c, 1 );
1399  }
1400 
1410  static OString valueOf( sal_Int32 i, sal_Int16 radix = 10 ) SAL_THROW(())
1411  {
1413  rtl_String* pNewData = 0;
1414  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfInt32( aBuf, i, radix ) );
1415  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1416  }
1417 
1427  static OString valueOf( sal_Int64 ll, sal_Int16 radix = 10 ) SAL_THROW(())
1428  {
1430  rtl_String* pNewData = 0;
1431  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfInt64( aBuf, ll, radix ) );
1432  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1433  }
1434 
1443  static OString valueOf( float f ) SAL_THROW(())
1444  {
1446  rtl_String* pNewData = 0;
1447  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfFloat( aBuf, f ) );
1448  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1449  }
1450 
1459  static OString valueOf( double d ) SAL_THROW(())
1460  {
1462  rtl_String* pNewData = 0;
1463  rtl_string_newFromStr_WithLength( &pNewData, aBuf, rtl_str_valueOfDouble( aBuf, d ) );
1464  return OString( pNewData, (DO_NOT_ACQUIRE*)0 );
1465  }
1466 };
1467 
1468 /* ======================================================================= */
1469 
1470 #ifdef RTL_FAST_STRING
1471 
1480 {
1481  template< int N >
1482  OStringLiteral( const char (&str)[ N ] ) : size( N - 1 ), data( str ) { assert( strlen( str ) == N - 1 ); }
1483  int size;
1484  const char* data;
1485 };
1486 
1487 template<>
1488 struct ToStringHelper< OString >
1489  {
1490  static int length( const OString& s ) { return s.getLength(); }
1491  static char* addData( char* buffer, const OString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
1492  static const bool allowOStringConcat = true;
1493  static const bool allowOUStringConcat = false;
1494  };
1495 
1496 template<>
1497 struct ToStringHelper< OStringLiteral >
1498  {
1499  static int length( const OStringLiteral& str ) { return str.size; }
1500  static char* addData( char* buffer, const OStringLiteral& str ) { return addDataHelper( buffer, str.data, str.size ); }
1501  static const bool allowOStringConcat = true;
1502  static const bool allowOUStringConcat = false;
1503  };
1504 
1505 template< typename charT, typename traits, typename T1, typename T2 >
1506 inline std::basic_ostream<charT, traits> & operator <<(
1507  std::basic_ostream<charT, traits> & stream, const OStringConcat< T1, T2 >& concat)
1508 {
1509  return stream << OString( concat );
1510 }
1511 #else
1512 // non-RTL_FAST_CODE needs this to compile
1514 #endif
1515 
1516 } /* Namespace */
1517 
1518 #ifdef RTL_STRING_UNITTEST
1519 namespace rtl
1520 {
1521 typedef rtlunittest::OString OString;
1522 }
1523 #undef RTL_STRING_CONST_FUNCTION
1524 #endif
1525 
1526 namespace rtl
1527 {
1528 
1535 {
1545  size_t operator()( const OString& rString ) const
1546  { return (size_t)rString.hashCode(); }
1547 };
1548 
1549 /* ======================================================================= */
1550 
1557 template< typename charT, typename traits > std::basic_ostream<charT, traits> &
1559  std::basic_ostream<charT, traits> & stream, rtl::OString const & string)
1560 {
1561  return stream << string.getStr();
1562  // best effort; potentially loses data due to embedded null characters
1563 }
1564 
1565 } /* Namespace */
1566 
1567 #ifdef RTL_USING
1568 using ::rtl::OString;
1569 using ::rtl::OStringHash;
1571 #endif
1572 
1573 #endif /* _RTL_STRING_HXX_ */
1574 
1575 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */