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 /*
21  * This file is part of LibreOffice published API.
22  */
23 
24 #ifndef INCLUDED_RTL_STRING_HXX
25 #define INCLUDED_RTL_STRING_HXX
26 
27 #include "sal/config.h"
28 
29 #include <cassert>
30 #include <cstddef>
31 #include <cstdlib>
32 #include <limits>
33 #include <new>
34 #include <ostream>
35 #include <utility>
36 #include <string.h>
37 
38 #if defined LIBO_INTERNAL_ONLY
39 #include <string_view>
40 #include <type_traits>
41 #endif
42 
43 #include "rtl/textenc.h"
44 #include "rtl/string.h"
45 #include "rtl/stringutils.hxx"
46 
47 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
48 #include "config_global.h"
49 #include "rtl/stringconcat.hxx"
50 #endif
51 
52 #ifdef RTL_STRING_UNITTEST
53 extern bool rtl_string_unittest_const_literal;
54 extern bool rtl_string_unittest_const_literal_function;
55 #endif
56 
57 // The unittest uses slightly different code to help check that the proper
58 // calls are made. The class is put into a different namespace to make
59 // sure the compiler generates a different (if generating also non-inline)
60 // copy of the function and does not merge them together. The class
61 // is "brought" into the proper rtl namespace by a typedef below.
62 #ifdef RTL_STRING_UNITTEST
63 #define rtl rtlunittest
64 #endif
65 
66 namespace rtl
67 {
68 
69 /// @cond INTERNAL
70 #ifdef RTL_STRING_UNITTEST
71 #undef rtl
72 // helper macro to make functions appear more readable
73 #define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
74 #else
75 #define RTL_STRING_CONST_FUNCTION
76 #endif
77 /// @endcond
78 
79 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
80 /**
81 A wrapper dressing a string literal as a static-refcount rtl_String.
82 
83 This class is not part of public API and is meant to be used only in LibreOffice code.
84 @since LibreOffice 4.0
85 */
86 template<std::size_t N> class SAL_WARN_UNUSED OStringLiteral {
87     static_assert(N != 0);
88     static_assert(N - 1 <= std::numeric_limits<sal_Int32>::max(), "literal too long");
89     friend class OString;
90 
91 public:
92 #if HAVE_CPP_CONSTEVAL
93     consteval
94 #else
95     constexpr
96 #endif
OStringLiteral(char const (& literal)[N])97     OStringLiteral(char const (&literal)[N]) {
98         assertLayout();
99         assert(literal[N - 1] == '\0');
100         //TODO: Use C++20 constexpr std::copy_n (P0202R3):
101         for (std::size_t i = 0; i != N; ++i) {
102             more.buffer[i] = literal[i];
103         }
104     }
105 
106 #if defined __cpp_char8_t
107 #if HAVE_CPP_CONSTEVAL
108     consteval
109 #else
110     constexpr
111 #endif
OStringLiteral(char8_t const (& literal)[N])112     explicit OStringLiteral(char8_t const (&literal)[N]) {
113         assertLayout();
114         assert(literal[N - 1] == '\0');
115         //TODO: Use C++20 constexpr std::copy_n (P0202R3):
116         for (std::size_t i = 0; i != N; ++i) {
117             more.buffer[i] = literal[i];
118         }
119     }
120 #endif
121 
getLength() const122     constexpr sal_Int32 getLength() const { return more.length; }
123 
getStr() const124     constexpr char const * getStr() const SAL_RETURNS_NONNULL { return more.buffer; }
125 
operator std::string_view() const126     constexpr operator std::string_view() const { return {more.buffer, sal_uInt32(more.length)}; }
127 
128 private:
assertLayout()129     static constexpr void assertLayout() {
130         // These static_asserts verifying the layout compatibility with rtl_String cannot be class
131         // member declarations, as offsetof requires a complete type, so defer them to here:
132         static_assert(offsetof(OStringLiteral, str.refCount) == offsetof(OStringLiteral, more.refCount));
133         static_assert(offsetof(OStringLiteral, str.length) == offsetof(OStringLiteral, more.length));
134         static_assert(offsetof(OStringLiteral, str.buffer) == offsetof(OStringLiteral, more.buffer));
135     }
136 
137     union {
138         rtl_String str;
139         struct {
140             oslInterlockedCount refCount;
141             sal_Int32 length;
142             char buffer[N];
143         } more =
144             {
145                 0x40000000, // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
146                 N - 1,
147                 {} //TODO: drop initialization for C++20 (P1331R2)
148             };
149     };
150 };
151 #endif
152 
153 /* ======================================================================= */
154 
155 /**
156   This String class provide base functionality for C++ like 8-Bit
157   character array handling. The advantage of this class is, that it
158   handle all the memory management for you - and it do it
159   more efficient. If you assign a string to another string, the
160   data of both strings are shared (without any copy operation or
161   memory allocation) as long as you do not change the string. This class
162   stores also the length of the string, so that many operations are
163   faster as the C-str-functions.
164 
165   This class provides only readonly string handling. So you could create
166   a string and you could only query the content from this string.
167   It provides also functionality to change the string, but this results
168   in every case in a new string instance (in the most cases with an
169   memory allocation). You don't have functionality to change the
170   content of the string. If you want to change the string content, then
171   you should use the OStringBuffer class, which provides these
172   functionalities and avoid too much memory allocation.
173 
174   The design of this class is similar to the string classes in Java
175   and so more people should have fewer understanding problems when they
176   use this class.
177 */
178 
179 class SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI OString
180 {
181 public:
182     /// @cond INTERNAL
183     rtl_String * pData;
184     /// @endcond
185 
186     /**
187       New string containing no characters.
188     */
OString()189     OString()
190     {
191         pData = NULL;
192         rtl_string_new( &pData );
193     }
194 
195     /**
196       New string from OString.
197 
198       @param    str         an OString.
199     */
OString(const OString & str)200     OString( const OString & str )
201     {
202         pData = str.pData;
203         rtl_string_acquire( pData );
204     }
205 
206 #if defined LIBO_INTERNAL_ONLY
207     /**
208       Move constructor.
209 
210       @param    str         an OString.
211       @since LibreOffice 5.2
212     */
OString(OString && str)213     OString( OString && str ) noexcept
214     {
215         pData = str.pData;
216         str.pData = nullptr;
217         rtl_string_new( &str.pData );
218     }
219 #endif
220 
221     /**
222       New string from OString data.
223 
224       @param    str         an OString data.
225     */
OString(rtl_String * str)226     OString( rtl_String * str )
227     {
228         pData = str;
229         rtl_string_acquire( pData );
230     }
231 
232     /** New string from OString data without acquiring it.  Takeover of ownership.
233 
234         The SAL_NO_ACQUIRE dummy parameter is only there to distinguish this
235         from other constructors.
236 
237       @param    str         an OString data.
238     */
OString(rtl_String * str,__sal_NoAcquire)239     OString( rtl_String * str, __sal_NoAcquire )
240     {
241         pData = str;
242     }
243 
244     /**
245       New string from a single character.
246 
247       @param    value       a character.
248     */
OString(char value)249     explicit OString( char value )
250         : pData (NULL)
251     {
252         rtl_string_newFromStr_WithLength( &pData, &value, 1 );
253     }
254 
255 #if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST_CONCAT
256     // Catch inadvertent conversions to the above ctor (e.g., from sal_[u]Int8, aka [un]signed
257     // char):
258     OString(int) = delete;
259 #endif
260 
261     /**
262       New string from a character buffer array.
263 
264       Note: The argument type is always either char* or const char*. The template is
265       used only for technical reasons, as is the second argument.
266 
267       @param    value       a NULL-terminated character array.
268     */
269     template< typename T >
OString(const T & value,typename libreoffice_internal::CharPtrDetector<T,libreoffice_internal::Dummy>::Type=libreoffice_internal::Dummy ())270     OString( const T& value, typename libreoffice_internal::CharPtrDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
271     {
272         pData = NULL;
273         rtl_string_newFromStr( &pData, value );
274     }
275 
276     template< typename T >
OString(T & value,typename libreoffice_internal::NonConstCharArrayDetector<T,libreoffice_internal::Dummy>::Type=libreoffice_internal::Dummy ())277     OString( T& value, typename libreoffice_internal::NonConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
278     {
279         pData = NULL;
280         rtl_string_newFromStr( &pData, value );
281     }
282 
283     /**
284       New string from a string literal.
285 
286       If there are any embedded \0's in the string literal, the result is undefined.
287       Use the overload that explicitly accepts length.
288 
289       @since LibreOffice 3.6
290 
291       @param    literal       a string literal
292     */
293     template< typename T >
OString(T & literal,typename libreoffice_internal::ConstCharArrayDetector<T,libreoffice_internal::Dummy>::Type=libreoffice_internal::Dummy ())294     OString( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
295     {
296         assert(
297             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
298         pData = NULL;
299         if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) {
300             rtl_string_new(&pData);
301         } else {
302             rtl_string_newFromLiteral(
303                 &pData,
304                 libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
305                     literal),
306                 libreoffice_internal::ConstCharArrayDetector<T>::length, 0);
307         }
308 #ifdef RTL_STRING_UNITTEST
309         rtl_string_unittest_const_literal = true;
310 #endif
311     }
312 
313     /**
314       New string from a character buffer array.
315 
316       @param    value       a character array.
317       @param    length      the number of character which should be copied.
318                             The character array length must be greater or
319                             equal than this value.
320     */
OString(const char * value,sal_Int32 length)321     OString( const char * value, sal_Int32 length )
322     {
323         pData = NULL;
324         rtl_string_newFromStr_WithLength( &pData, value, length );
325     }
326 
327 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
328     /// @cond INTERNAL
329     /**
330       New string from an 8-Bit string literal.
331 
332       @since LibreOffice 7.1
333     */
OString(OStringLiteral<N> const & literal)334     template<std::size_t N> constexpr OString(OStringLiteral<N> const & literal):
335         pData(const_cast<rtl_String *>(&literal.str)) {}
336     template<std::size_t N> OString(OStringLiteral<N> &&) = delete;
337     /// @endcond
338 #endif
339 
340 #if defined LIBO_INTERNAL_ONLY
OString(std::string_view sv)341     explicit OString(std::string_view sv) {
342         if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
343             throw std::bad_alloc();
344         }
345         pData = nullptr;
346         rtl_string_newFromStr_WithLength(&pData, sv.data(), sv.size());
347     }
348 #endif
349 
350     /**
351       New string from a Unicode character buffer array.
352 
353       @param    value           a Unicode character array.
354       @param    length          the number of character which should be converted.
355                                 The Unicode character array length must be
356                                 greater or equal than this value.
357       @param    encoding        the text encoding in which the Unicode character
358                                 sequence should be converted.
359       @param    convertFlags    flags which controls the conversion.
360                                 see RTL_UNICODETOTEXT_FLAGS_...
361 
362       @exception std::bad_alloc is thrown if an out-of-memory condition occurs
363     */
OString(const sal_Unicode * value,sal_Int32 length,rtl_TextEncoding encoding,sal_uInt32 convertFlags=OUSTRING_TO_OSTRING_CVTFLAGS)364     OString( const sal_Unicode * value, sal_Int32 length,
365              rtl_TextEncoding encoding,
366              sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
367     {
368         pData = NULL;
369         rtl_uString2String( &pData, value, length, encoding, convertFlags );
370         if (pData == NULL) {
371             throw std::bad_alloc();
372         }
373     }
374 
375 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
376     /**
377      @overload
378      @internal
379     */
380     template< typename T1, typename T2 >
OString(OStringConcat<T1,T2> && c)381     OString( OStringConcat< T1, T2 >&& c )
382     {
383         const sal_Int32 l = c.length();
384         pData = rtl_string_alloc( l );
385         if (l != 0)
386         {
387             char* end = c.addData( pData->buffer );
388             pData->length = l;
389             *end = '\0';
390         }
391     }
392 
393     /**
394      @overload
395      @internal
396     */
397     template< typename T >
OString(OStringNumber<T> && n)398     OString( OStringNumber< T >&& n )
399         : OString( n.buf, n.length )
400     {}
401 #endif
402 
403 #ifdef LIBO_INTERNAL_ONLY
404     OString(std::nullptr_t) = delete;
405 #endif
406 
407     /**
408       Release the string data.
409     */
~OString()410     ~OString()
411     {
412         rtl_string_release( pData );
413     }
414 
415     /**
416       Assign a new string.
417 
418       @param    str         an OString.
419     */
operator =(const OString & str)420     OString & operator=( const OString & str )
421     {
422         rtl_string_assign( &pData, str.pData );
423         return *this;
424     }
425 
426 #if defined LIBO_INTERNAL_ONLY
427     /**
428       Move assign a new string.
429 
430       @param    str         an OString.
431       @since LibreOffice 5.2
432     */
operator =(OString && str)433     OString & operator=( OString && str ) noexcept
434     {
435         rtl_string_release( pData );
436         pData = str.pData;
437         str.pData = nullptr;
438         rtl_string_new( &str.pData );
439         return *this;
440     }
441 #endif
442 
443     /**
444      @overload
445      This function accepts an ASCII string literal as its argument.
446      @since LibreOffice 3.6
447     */
448     template< typename T >
operator =(T & literal)449     typename libreoffice_internal::ConstCharArrayDetector< T, OString& >::Type operator=( T& literal )
450     {
451         RTL_STRING_CONST_FUNCTION
452         assert(
453             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
454         if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) {
455             rtl_string_new(&pData);
456         } else {
457             rtl_string_newFromLiteral(
458                 &pData,
459                 libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
460                     literal),
461                 libreoffice_internal::ConstCharArrayDetector<T>::length, 0);
462         }
463         return *this;
464     }
465 
466     /**
467       Append a string to this string.
468 
469       @param    str         an OString.
470     */
operator +=(const OString & str)471     OString & operator+=( const OString & str )
472 #if defined LIBO_INTERNAL_ONLY
473         &
474 #endif
475     {
476         rtl_string_newConcat( &pData, pData, str.pData );
477         return *this;
478     }
479 #if defined LIBO_INTERNAL_ONLY
480     void operator+=(OString const &) && = delete;
481 #endif
482 
483 #if defined LIBO_INTERNAL_ONLY
484     template<typename T> typename libreoffice_internal::CharPtrDetector<T, OString &>::Type
operator +=(T const & value)485     operator +=(T const & value) & { return operator +=(std::string_view(value)); }
486     template<typename T> typename libreoffice_internal::CharPtrDetector<T, OString &>::Type
487     operator +=(T const &) && = delete;
488 
489     template<typename T>
490     typename libreoffice_internal::NonConstCharArrayDetector<T, OString &>::Type
operator +=(T & value)491     operator +=(T & value) & { return operator +=(std::string_view(value)); }
492     template<typename T>
493     typename libreoffice_internal::NonConstCharArrayDetector<T, OString &>::Type operator +=(T &) &&
494         = delete;
495 
496     template<typename T> typename libreoffice_internal::ConstCharArrayDetector<T, OString &>::Type
operator +=(T & literal)497     operator +=(T & literal) & {
498         assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
499         return operator +=(
500             std::string_view(
501                 libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
502                 libreoffice_internal::ConstCharArrayDetector<T>::length));
503     }
504     template<typename T> typename libreoffice_internal::ConstCharArrayDetector<T, OString &>::Type
505     operator +=(T &) && = delete;
506 
operator +=(OStringLiteral<N> const & literal)507     template<std::size_t N> OString & operator +=(OStringLiteral<N> const & literal) &
508     { return operator +=(std::string_view(literal.getStr(), literal.getLength())); }
509     template<std::size_t N> void operator +=(OStringLiteral<N> const &) && = delete;
510 
operator +=(std::string_view sv)511     OString & operator +=(std::string_view sv) & {
512         if (sv.empty()) {
513             return *this;
514         }
515         if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max() - pData->length)) {
516             throw std::bad_alloc();
517         }
518         auto const l = pData->length + sv.size();
519         rtl_string_ensureCapacity(&pData, l);
520         *addDataHelper(pData->buffer + pData->length, sv.data(), sv.size()) = '\0';
521         pData->length = l;
522         return *this;
523     }
524     void operator +=(std::string_view) && = delete;
525 #endif
526 
527 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
528     /**
529      @overload
530      @internal
531     */
532     template< typename T1, typename T2 >
operator +=(OStringConcat<T1,T2> && c)533     OString& operator+=( OStringConcat< T1, T2 >&& c ) & {
534         sal_Int32 l = c.length();
535         if( l == 0 )
536             return *this;
537         l += pData->length;
538         rtl_string_ensureCapacity( &pData, l );
539         char* end = c.addData( pData->buffer + pData->length );
540         *end = '\0';
541         pData->length = l;
542         return *this;
543     }
544     template<typename T1, typename T2> void operator +=(
545         OStringConcat<T1, T2> &&) && = delete;
546 
547     /**
548      @overload
549      @internal
550     */
551     template< typename T >
operator +=(OStringNumber<T> && n)552     OString& operator+=( OStringNumber< T >&& n ) & {
553         return operator +=(std::string_view(n.buf, n.length));
554     }
555     template<typename T> void operator +=(
556         OStringNumber<T> &&) && = delete;
557 #endif
558 
559     /**
560       Clears the string, i.e, makes a zero-character string
561       @since LibreOffice 4.4
562     */
clear()563     void clear()
564     {
565         rtl_string_new( &pData );
566     }
567 
568     /**
569       Returns the length of this string.
570 
571       The length is equal to the number of characters in this string.
572 
573       @return   the length of the sequence of characters represented by this
574                 object.
575     */
getLength() const576     sal_Int32 getLength() const { return pData->length; }
577 
578     /**
579       Checks if a string is empty.
580 
581       @return   true if the string is empty;
582                 false, otherwise.
583 
584       @since LibreOffice 3.4
585     */
isEmpty() const586     bool isEmpty() const
587     {
588         return pData->length == 0;
589     }
590 
591     /**
592       Returns a pointer to the characters of this string.
593 
594       <p>The returned pointer is guaranteed to point to a null-terminated byte
595       string.  But note that this string object may contain embedded null
596       characters, which will thus also be embedded in the returned
597       null-terminated byte string.</p>
598 
599       @return a pointer to a null-terminated byte string representing the
600       characters of this string object.
601     */
getStr() const602     const char * getStr() const SAL_RETURNS_NONNULL { return pData->buffer; }
603 
604     /**
605       Access to individual characters.
606 
607       @param index must be non-negative and less than length.
608 
609       @return the character at the given index.
610 
611       @since LibreOffice 3.5
612     */
operator [](sal_Int32 index) const613     char operator [](sal_Int32 index) const {
614         // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2
615         assert(index >= 0 && static_cast<sal_uInt32>(index) < static_cast<sal_uInt32>(getLength()));
616         return getStr()[index];
617     }
618 
619     /**
620       Compares two strings.
621 
622       The comparison is based on the numeric value of each character in
623       the strings and return a value indicating their relationship.
624       This function can't be used for language specific sorting.
625 
626       @param    str         the object to be compared.
627       @return   0 - if both strings are equal
628                 < 0 - if this string is less than the string argument
629                 > 0 - if this string is greater than the string argument
630     */
compareTo(const OString & str) const631     sal_Int32 compareTo( const OString & str ) const
632     {
633         return rtl_str_compare_WithLength( pData->buffer, pData->length,
634                                            str.pData->buffer, str.pData->length );
635     }
636 
637     /**
638       Compares two strings with an maximum count of characters.
639 
640       The comparison is based on the numeric value of each character in
641       the strings and return a value indicating their relationship.
642       This function can't be used for language specific sorting.
643 
644       @param    rObj        the object to be compared.
645       @param    maxLength   the maximum count of characters to be compared.
646       @return   0 - if both strings are equal
647                 < 0 - if this string is less than the string argument
648                 > 0 - if this string is greater than the string argument
649     */
compareTo(const OString & rObj,sal_Int32 maxLength) const650     sal_Int32 compareTo( const OString & rObj, sal_Int32 maxLength ) const
651     {
652         return rtl_str_shortenedCompare_WithLength( pData->buffer, pData->length,
653                                                     rObj.pData->buffer, rObj.pData->length, maxLength );
654     }
655 
656     /**
657       Compares two strings in reverse order.
658 
659       The comparison is based on the numeric value of each character in
660       the strings and return a value indicating their relationship.
661       This function can't be used for language specific sorting.
662 
663       @param    str         the object to be compared.
664       @return   0 - if both strings are equal
665                 < 0 - if this string is less than the string argument
666                 > 0 - if this string is greater than the string argument
667     */
reverseCompareTo(const OString & str) const668     sal_Int32 reverseCompareTo( const OString & str ) const
669     {
670         return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
671                                                   str.pData->buffer, str.pData->length );
672     }
673 
674     /**
675       Perform a comparison of two strings.
676 
677       The result is true if and only if second string
678       represents the same sequence of characters as the first string.
679       This function can't be used for language specific comparison.
680 
681       @param    str         the object to be compared.
682       @return   true if the strings are equal;
683                 false, otherwise.
684     */
equals(const OString & str) const685     bool equals( const OString & str ) const
686     {
687         if ( pData->length != str.pData->length )
688             return false;
689         if ( pData == str.pData )
690             return true;
691         return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
692                                                   str.pData->buffer, str.pData->length ) == 0;
693     }
694 
695     /**
696       Perform a comparison of two strings.
697 
698       The result is true if and only if second string
699       represents the same sequence of characters as the first string.
700       The ASCII string must be NULL-terminated and must be greater or
701       equal as length.
702       This function can't be used for language specific comparison.
703 
704 
705       @param    value       a character array.
706       @param    length      the length of the character array.
707       @return   true if the strings are equal;
708                 false, otherwise.
709     */
equalsL(const char * value,sal_Int32 length) const710     bool equalsL( const char* value, sal_Int32 length ) const
711     {
712         if ( pData->length != length )
713             return false;
714 
715         return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
716                                                   value, length ) == 0;
717     }
718 
719     /**
720       Perform an ASCII lowercase comparison of two strings.
721 
722       The result is true if and only if second string
723       represents the same sequence of characters as the first string,
724       ignoring the case.
725       Character values between 65 and 90 (ASCII A-Z) are interpreted as
726       values between 97 and 122 (ASCII a-z).
727       This function can't be used for language specific comparison.
728 
729       @param    str         the object to be compared.
730       @return   true if the strings are equal;
731                 false, otherwise.
732     */
733 #if defined LIBO_INTERNAL_ONLY
equalsIgnoreAsciiCase(std::string_view str) const734     bool equalsIgnoreAsciiCase( std::string_view str ) const
735     {
736         if ( sal_uInt32(pData->length) != str.size() )
737             return false;
738         if ( pData->buffer == str.data() )
739             return true;
740         return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
741                                                           str.data(), str.size() ) == 0;
742     }
743 #else
equalsIgnoreAsciiCase(const OString & str) const744     bool equalsIgnoreAsciiCase( const OString & str ) const
745     {
746         if ( pData->length != str.pData->length )
747             return false;
748         if ( pData == str.pData )
749             return true;
750         return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
751                                                           str.pData->buffer, str.pData->length ) == 0;
752     }
753 #endif
754 
755     /**
756       Perform an ASCII lowercase comparison of two strings.
757 
758       The result is true if and only if second string
759       represents the same sequence of characters as the first string,
760       ignoring the case.
761       Character values between 65 and 90 (ASCII A-Z) are interpreted as
762       values between 97 and 122 (ASCII a-z).
763       Since this method is optimized for performance, the ASCII character
764       values are not converted in any way. The caller has to make sure that
765       all ASCII characters are in the allowed range between 0 and
766       127. The ASCII string must be NULL-terminated.
767       This function can't be used for language specific comparison.
768 
769       Note: The argument type is always either char* or const char*, the return type is bool.
770       The template is used only for technical reasons.
771 
772       @param    asciiStr        the 8-Bit ASCII character string to be compared.
773       @return   true if the strings are equal;
774                 false, otherwise.
775     */
776     template< typename T >
equalsIgnoreAsciiCase(const T & asciiStr) const777     typename libreoffice_internal::CharPtrDetector< T, bool >::Type equalsIgnoreAsciiCase( const T& asciiStr ) const
778     {
779         return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
780     }
781 
782     template< typename T >
equalsIgnoreAsciiCase(T & asciiStr) const783     typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& asciiStr ) const
784     {
785         return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
786     }
787 
788     /**
789      @overload
790      This function accepts an ASCII string literal as its argument.
791      @since LibreOffice 3.6
792     */
793     template< typename T >
equalsIgnoreAsciiCase(T & literal) const794     typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type  equalsIgnoreAsciiCase( T& literal ) const
795     {
796         RTL_STRING_CONST_FUNCTION
797         assert(
798             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
799         return
800             (pData->length
801              == libreoffice_internal::ConstCharArrayDetector<T>::length)
802             && (rtl_str_compareIgnoreAsciiCase_WithLength(
803                     pData->buffer, pData->length,
804                     libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
805                         literal),
806                     libreoffice_internal::ConstCharArrayDetector<T>::length)
807                 == 0);
808     }
809 
810     /**
811       Perform an ASCII lowercase comparison of two strings.
812 
813       The result is true if and only if second string
814       represents the same sequence of characters as the first string,
815       ignoring the case.
816       Character values between 65 and 90 (ASCII A-Z) are interpreted as
817       values between 97 and 122 (ASCII a-z).
818       Since this method is optimized for performance, the ASCII character
819       values are not converted in any way. The caller has to make sure that
820       all ASCII characters are in the allowed range between 0 and
821       127. The ASCII string must be greater or equal in length as asciiStrLength.
822       This function can't be used for language specific comparison.
823 
824       @param    asciiStr        the 8-Bit ASCII character string to be compared.
825       @param    asciiStrLength  the length of the ascii string
826       @return   true if the strings are equal;
827                 false, otherwise.
828     */
equalsIgnoreAsciiCaseL(const char * asciiStr,sal_Int32 asciiStrLength) const829     bool equalsIgnoreAsciiCaseL( const char * asciiStr, sal_Int32 asciiStrLength ) const
830     {
831         if ( pData->length != asciiStrLength )
832             return false;
833 
834         return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
835                                                           asciiStr, asciiStrLength ) == 0;
836     }
837 
838     /**
839       Match against a substring appearing in this string.
840 
841       The result is true if and only if the second string appears as a substring
842       of this string, at the given position.
843       This function can't be used for language specific comparison.
844 
845       @param    str         the object (substring) to be compared.
846       @param    fromIndex   the index to start the comparison from.
847                             The index must be greater or equal than 0
848                             and less or equal as the string length.
849       @return   true if str match with the characters in the string
850                 at the given position;
851                 false, otherwise.
852     */
853 #if defined LIBO_INTERNAL_ONLY
match(std::string_view str,sal_Int32 fromIndex=0) const854     bool match( std::string_view str, sal_Int32 fromIndex = 0 ) const
855     {
856         return rtl_str_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
857                                                     str.data(), str.size(), str.size() ) == 0;
858     }
859 #else
match(const OString & str,sal_Int32 fromIndex=0) const860     bool match( const OString & str, sal_Int32 fromIndex = 0 ) const
861     {
862         return rtl_str_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
863                                                     str.pData->buffer, str.pData->length, str.pData->length ) == 0;
864     }
865 #endif
866 
867     /**
868      @overload
869      This function accepts an ASCII string literal as its argument.
870      @since LibreOffice 3.6
871     */
872     template< typename T >
match(T & literal,sal_Int32 fromIndex=0) const873     typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type  match( T& literal, sal_Int32 fromIndex = 0 ) const
874     {
875         RTL_STRING_CONST_FUNCTION
876         assert(
877             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
878         return
879             rtl_str_shortenedCompare_WithLength(
880                 pData->buffer + fromIndex, pData->length - fromIndex,
881                 libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
882                     literal),
883                 libreoffice_internal::ConstCharArrayDetector<T>::length,
884                 libreoffice_internal::ConstCharArrayDetector<T>::length)
885             == 0;
886     }
887 
888     /**
889       Match against a substring appearing in this string.
890 
891       @param str  the substring to be compared; must not be null and must point
892       to memory of at least strLength bytes
893 
894       @param strLength  the length of the substring; must be non-negative
895 
896       @param fromIndex  the index into this string to start the comparison at;
897       must be non-negative and not greater than this string's length
898 
899       @return true if and only if the given str is contained as a substring of
900       this string at the given fromIndex
901 
902       @since LibreOffice 3.6
903     */
matchL(char const * str,sal_Int32 strLength,sal_Int32 fromIndex=0) const904     bool matchL(
905         char const * str, sal_Int32 strLength, sal_Int32 fromIndex = 0)
906         const
907     {
908         return rtl_str_shortenedCompare_WithLength(
909             pData->buffer + fromIndex, pData->length - fromIndex,
910             str, strLength, strLength) == 0;
911     }
912 
913     // This overload is left undefined, to detect calls of matchL that
914     // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
915     // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
916     // platforms):
917 #if SAL_TYPES_SIZEOFLONG == 8
918     void matchL(char const *, sal_Int32, rtl_TextEncoding) const;
919 #endif
920 
921     /**
922       Match against a substring appearing in this string, ignoring the case of
923       ASCII letters.
924 
925       The result is true if and only if the second string appears as a substring
926       of this string, at the given position.
927       Character values between 65 and 90 (ASCII A-Z) are interpreted as
928       values between 97 and 122 (ASCII a-z).
929       This function can't be used for language specific comparison.
930 
931       @param    str         the object (substring) to be compared.
932       @param    fromIndex   the index to start the comparison from.
933                             The index must be greater or equal than 0
934                             and less or equal as the string length.
935       @return   true if str match with the characters in the string
936                 at the given position;
937                 false, otherwise.
938     */
939 #if defined LIBO_INTERNAL_ONLY
matchIgnoreAsciiCase(std::string_view str,sal_Int32 fromIndex=0) const940     bool matchIgnoreAsciiCase( std::string_view str, sal_Int32 fromIndex = 0 ) const
941     {
942         return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
943                                                                    str.data(), str.size(),
944                                                                    str.size() ) == 0;
945     }
946 #else
matchIgnoreAsciiCase(const OString & str,sal_Int32 fromIndex=0) const947     bool matchIgnoreAsciiCase( const OString & str, sal_Int32 fromIndex = 0 ) const
948     {
949         return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
950                                                                    str.pData->buffer, str.pData->length,
951                                                                    str.pData->length ) == 0;
952     }
953 #endif
954     /**
955      @overload
956      This function accepts an ASCII string literal as its argument.
957      @since LibreOffice 3.6
958     */
959     template< typename T >
matchIgnoreAsciiCase(T & literal,sal_Int32 fromIndex=0) const960     typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const
961     {
962         RTL_STRING_CONST_FUNCTION
963         assert(
964             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
965         return
966             rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
967                 pData->buffer+fromIndex, pData->length-fromIndex,
968                 libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
969                     literal),
970                 libreoffice_internal::ConstCharArrayDetector<T>::length,
971                 libreoffice_internal::ConstCharArrayDetector<T>::length)
972             == 0;
973     }
974 
975     /**
976       Check whether this string starts with a given substring.
977 
978       @param str the substring to be compared
979 
980       @param rest if non-null, and this function returns true, then assign a
981       copy of the remainder of this string to *rest. Available since
982       LibreOffice 4.2
983 
984       @return true if and only if the given str appears as a substring at the
985       start of this string
986 
987       @since LibreOffice 4.0
988     */
989 #if defined LIBO_INTERNAL_ONLY
startsWith(std::string_view str,OString * rest=NULL) const990     bool startsWith(std::string_view str, OString * rest = NULL) const {
991         bool b = match(str);
992         if (b && rest != NULL) {
993             *rest = copy(str.size());
994         }
995         return b;
996     }
997 #else
startsWith(OString const & str,OString * rest=NULL) const998     bool startsWith(OString const & str, OString * rest = NULL) const {
999         bool b = match(str);
1000         if (b && rest != NULL) {
1001             *rest = copy(str.getLength());
1002         }
1003         return b;
1004     }
1005 #endif
1006 
1007     /**
1008      @overload
1009      This function accepts an ASCII string literal as its argument.
1010      @since LibreOffice 4.0
1011     */
1012     template< typename T >
startsWith(T & literal,OString * rest=NULL) const1013     typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type startsWith(
1014         T & literal, OString * rest = NULL) const
1015     {
1016         RTL_STRING_CONST_FUNCTION
1017         bool b = match(literal, 0);
1018         if (b && rest != NULL) {
1019             *rest = copy(
1020                 libreoffice_internal::ConstCharArrayDetector<T>::length);
1021         }
1022         return b;
1023     }
1024 
1025     /**
1026       Check whether this string starts with a given string, ignoring the case of
1027       ASCII letters.
1028 
1029       Character values between 65 and 90 (ASCII A-Z) are interpreted as
1030       values between 97 and 122 (ASCII a-z).
1031       This function can't be used for language specific comparison.
1032 
1033       @param str the substring to be compared
1034 
1035       @param rest if non-null, and this function returns true, then assign a
1036       copy of the remainder of this string to *rest.
1037 
1038       @return true if and only if the given str appears as a substring at the
1039       start of this string, ignoring the case of ASCII letters ("A"--"Z" and
1040       "a"--"z")
1041 
1042       @since LibreOffice 5.1
1043     */
1044 #if defined LIBO_INTERNAL_ONLY
startsWithIgnoreAsciiCase(std::string_view str,OString * rest=NULL) const1045     bool startsWithIgnoreAsciiCase(std::string_view str, OString * rest = NULL)
1046         const
1047     {
1048         bool b = matchIgnoreAsciiCase(str);
1049         if (b && rest != NULL) {
1050             *rest = copy(str.size());
1051         }
1052         return b;
1053     }
1054 #else
startsWithIgnoreAsciiCase(OString const & str,OString * rest=NULL) const1055     bool startsWithIgnoreAsciiCase(OString const & str, OString * rest = NULL)
1056         const
1057     {
1058         bool b = matchIgnoreAsciiCase(str);
1059         if (b && rest != NULL) {
1060             *rest = copy(str.getLength());
1061         }
1062         return b;
1063     }
1064 #endif
1065 
1066     /**
1067      @overload
1068      This function accepts an ASCII string literal as its argument.
1069      @since LibreOffice 5.1
1070     */
1071     template< typename T >
1072     typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type
startsWithIgnoreAsciiCase(T & literal,OString * rest=NULL) const1073     startsWithIgnoreAsciiCase(T & literal, OString * rest = NULL) const
1074     {
1075         RTL_STRING_CONST_FUNCTION
1076         assert(
1077             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1078         bool b = matchIgnoreAsciiCase(literal);
1079         if (b && rest != NULL) {
1080             *rest = copy(
1081                 libreoffice_internal::ConstCharArrayDetector<T>::length);
1082         }
1083         return b;
1084     }
1085 
1086     /**
1087       Check whether this string ends with a given substring.
1088 
1089       @param str the substring to be compared
1090 
1091       @param rest if non-null, and this function returns true, then assign a
1092       copy of the remainder of this string to *rest. Available since
1093       LibreOffice 4.2
1094 
1095       @return true if and only if the given str appears as a substring at the
1096       end of this string
1097 
1098       @since LibreOffice 3.6
1099     */
1100 #if defined LIBO_INTERNAL_ONLY
endsWith(std::string_view str,OString * rest=NULL) const1101     bool endsWith(std::string_view str, OString * rest = NULL) const {
1102         bool b = str.size() <= sal_uInt32(getLength())
1103             && match(str, getLength() - str.size());
1104         if (b && rest != NULL) {
1105             *rest = copy(0, getLength() - str.size());
1106         }
1107         return b;
1108     }
1109 #else
endsWith(OString const & str,OString * rest=NULL) const1110     bool endsWith(OString const & str, OString * rest = NULL) const {
1111         bool b = str.getLength() <= getLength()
1112             && match(str, getLength() - str.getLength());
1113         if (b && rest != NULL) {
1114             *rest = copy(0, getLength() - str.getLength());
1115         }
1116         return b;
1117     }
1118 #endif
1119 
1120     /**
1121      @overload
1122      This function accepts an ASCII string literal as its argument.
1123      @since LibreOffice 3.6
1124     */
1125     template< typename T >
endsWith(T & literal,OString * rest=NULL) const1126     typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type endsWith(
1127         T & literal, OString * rest = NULL) const
1128     {
1129         RTL_STRING_CONST_FUNCTION
1130         assert(
1131             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1132         bool b
1133             = (libreoffice_internal::ConstCharArrayDetector<T>::length
1134                <= sal_uInt32(getLength()))
1135             && match(
1136                 libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
1137                     literal),
1138                 (getLength()
1139                  - libreoffice_internal::ConstCharArrayDetector<T>::length));
1140         if (b && rest != NULL) {
1141             *rest = copy(
1142                 0,
1143                 (getLength()
1144                  - libreoffice_internal::ConstCharArrayDetector<T>::length));
1145         }
1146         return b;
1147     }
1148 
1149     /**
1150       Check whether this string ends with a given substring.
1151 
1152       @param str  the substring to be compared; must not be null and must point
1153       to memory of at least strLength bytes
1154 
1155       @param strLength  the length of the substring; must be non-negative
1156 
1157       @return true if and only if the given str appears as a substring at the
1158       end of this string
1159 
1160       @since LibreOffice 3.6
1161     */
endsWithL(char const * str,sal_Int32 strLength) const1162     bool endsWithL(char const * str, sal_Int32 strLength) const {
1163         return strLength <= getLength()
1164             && matchL(str, strLength, getLength() - strLength);
1165     }
1166 
operator ==(const OString & rStr1,const OString & rStr2)1167     friend bool     operator == ( const OString& rStr1, const OString& rStr2 )
1168                         { return rStr1.equals(rStr2); }
operator !=(const OString & rStr1,const OString & rStr2)1169     friend bool     operator != ( const OString& rStr1,     const OString& rStr2 )
1170                         { return !(operator == ( rStr1, rStr2 )); }
operator <(const OString & rStr1,const OString & rStr2)1171     friend bool     operator <  ( const OString& rStr1,    const OString& rStr2 )
1172                         { return rStr1.compareTo( rStr2 ) < 0; }
operator >(const OString & rStr1,const OString & rStr2)1173     friend bool     operator >  ( const OString& rStr1,    const OString& rStr2 )
1174                         { return rStr1.compareTo( rStr2 ) > 0; }
operator <=(const OString & rStr1,const OString & rStr2)1175     friend bool     operator <= ( const OString& rStr1,    const OString& rStr2 )
1176                         { return rStr1.compareTo( rStr2 ) <= 0; }
operator >=(const OString & rStr1,const OString & rStr2)1177     friend bool     operator >= ( const OString& rStr1,    const OString& rStr2 )
1178                         { return rStr1.compareTo( rStr2 ) >= 0; }
1179 
1180     template< typename T >
operator ==(const OString & rStr1,const T & value)1181     friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator==( const OString& rStr1, const T& value )
1182     {
1183         return rStr1.compareTo( value ) == 0;
1184     }
1185 
1186     template< typename T >
operator ==(const OString & rStr1,T & value)1187     friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator==( const OString& rStr1, T& value )
1188     {
1189         return rStr1.compareTo( value ) == 0;
1190     }
1191 
1192     template< typename T >
operator ==(const T & value,const OString & rStr2)1193     friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator==( const T& value, const OString& rStr2 )
1194     {
1195         return rStr2.compareTo( value ) == 0;
1196     }
1197 
1198     template< typename T >
operator ==(T & value,const OString & rStr2)1199     friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator==( T& value, const OString& rStr2 )
1200     {
1201         return rStr2.compareTo( value ) == 0;
1202     }
1203 
1204     /**
1205      @overload
1206      This function accepts an ASCII string literal as its argument.
1207      @since LibreOffice 3.6
1208     */
1209     template< typename T >
operator ==(const OString & rStr,T & literal)1210     friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( const OString& rStr, T& literal )
1211     {
1212         RTL_STRING_CONST_FUNCTION
1213         assert(
1214             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1215         return
1216             (rStr.getLength()
1217              == libreoffice_internal::ConstCharArrayDetector<T>::length)
1218             && (rtl_str_compare_WithLength(
1219                     rStr.pData->buffer, rStr.pData->length,
1220                     libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
1221                         literal),
1222                     libreoffice_internal::ConstCharArrayDetector<T>::length)
1223                 == 0);
1224     }
1225 
1226     /**
1227      @overload
1228      This function accepts an ASCII string literal as its argument.
1229      @since LibreOffice 3.6
1230     */
1231     template< typename T >
operator ==(T & literal,const OString & rStr)1232     friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OString& rStr )
1233     {
1234         RTL_STRING_CONST_FUNCTION
1235         assert(
1236             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1237         return
1238             (rStr.getLength()
1239              == libreoffice_internal::ConstCharArrayDetector<T>::length)
1240             && (rtl_str_compare_WithLength(
1241                     rStr.pData->buffer, rStr.pData->length,
1242                     libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
1243                         literal),
1244                     libreoffice_internal::ConstCharArrayDetector<T>::length)
1245                 == 0);
1246     }
1247 
1248     template< typename T >
operator !=(const OString & rStr1,const T & value)1249     friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator!=( const OString& rStr1, const T& value )
1250     {
1251         return !(operator == ( rStr1, value ));
1252     }
1253 
1254     template< typename T >
operator !=(const OString & rStr1,T & value)1255     friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator!=( const OString& rStr1, T& value )
1256     {
1257         return !(operator == ( rStr1, value ));
1258     }
1259 
1260     template< typename T >
operator !=(const T & value,const OString & rStr2)1261     friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator!=( const T& value,   const OString& rStr2 )
1262     {
1263         return !(operator == ( value, rStr2 ));
1264     }
1265 
1266     template< typename T >
operator !=(T & value,const OString & rStr2)1267     friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator!=( T& value,   const OString& rStr2 )
1268     {
1269         return !(operator == ( value, rStr2 ));
1270     }
1271 
1272     /**
1273      @overload
1274      This function accepts an ASCII string literal as its argument.
1275      @since LibreOffice 3.6
1276     */
1277     template< typename T >
operator !=(const OString & rStr,T & literal)1278     friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OString& rStr, T& literal )
1279     {
1280         return !( rStr == literal );
1281     }
1282 
1283     /**
1284      @overload
1285      This function accepts an ASCII string literal as its argument.
1286      @since LibreOffice 3.6
1287     */
1288     template< typename T >
operator !=(T & literal,const OString & rStr)1289     friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OString& rStr )
1290     {
1291         return !( literal == rStr );
1292     }
1293 
1294     /**
1295       Returns a hashcode for this string.
1296 
1297       @return   a hash code value for this object.
1298 
1299       @see rtl::OStringHash for convenient use of std::unordered_map
1300     */
hashCode() const1301     sal_Int32 hashCode() const
1302     {
1303         return rtl_str_hashCode_WithLength( pData->buffer, pData->length );
1304     }
1305 
1306     /**
1307       Returns the index within this string of the first occurrence of the
1308       specified character, starting the search at the specified index.
1309 
1310       @param    ch          character to be located.
1311       @param    fromIndex   the index to start the search from.
1312                             The index must be greater or equal than 0
1313                             and less or equal as the string length.
1314       @return   the index of the first occurrence of the character in the
1315                 character sequence represented by this string that is
1316                 greater than or equal to fromIndex, or
1317                 -1 if the character does not occur.
1318     */
indexOf(char ch,sal_Int32 fromIndex=0) const1319     sal_Int32 indexOf( char ch, sal_Int32 fromIndex = 0 ) const
1320     {
1321         sal_Int32 ret = rtl_str_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
1322         return (ret < 0 ? ret : ret+fromIndex);
1323     }
1324 
1325     /**
1326       Returns the index within this string of the last occurrence of the
1327       specified character, searching backward starting at the end.
1328 
1329       @param    ch          character to be located.
1330       @return   the index of the last occurrence of the character in the
1331                 character sequence represented by this string, or
1332                 -1 if the character does not occur.
1333     */
lastIndexOf(char ch) const1334     sal_Int32 lastIndexOf( char ch ) const
1335     {
1336         return rtl_str_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
1337     }
1338 
1339     /**
1340       Returns the index within this string of the last occurrence of the
1341       specified character, searching backward starting before the specified
1342       index.
1343 
1344       @param    ch          character to be located.
1345       @param    fromIndex   the index before which to start the search.
1346       @return   the index of the last occurrence of the character in the
1347                 character sequence represented by this string that
1348                 is less than fromIndex, or -1
1349                 if the character does not occur before that point.
1350     */
lastIndexOf(char ch,sal_Int32 fromIndex) const1351     sal_Int32 lastIndexOf( char ch, sal_Int32 fromIndex ) const
1352     {
1353         return rtl_str_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
1354     }
1355 
1356     /**
1357       Returns the index within this string of the first occurrence of the
1358       specified substring, starting at the specified index.
1359 
1360       If str doesn't include any character, always -1 is
1361       returned. This is also the case, if both strings are empty.
1362 
1363       @param    str         the substring to search for.
1364       @param    fromIndex   the index to start the search from.
1365       @return   If the string argument occurs one or more times as a substring
1366                 within this string at the starting index, then the index
1367                 of the first character of the first such substring is
1368                 returned. If it does not occur as a substring starting
1369                 at fromIndex or beyond, -1 is returned.
1370     */
1371 #if defined LIBO_INTERNAL_ONLY
indexOf(std::string_view str,sal_Int32 fromIndex=0) const1372     sal_Int32 indexOf( std::string_view str, sal_Int32 fromIndex = 0 ) const
1373     {
1374         sal_Int32 ret = rtl_str_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1375                                                        str.data(), str.size() );
1376         return (ret < 0 ? ret : ret+fromIndex);
1377     }
1378 #else
indexOf(const OString & str,sal_Int32 fromIndex=0) const1379     sal_Int32 indexOf( const OString & str, sal_Int32 fromIndex = 0 ) const
1380     {
1381         sal_Int32 ret = rtl_str_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1382                                                        str.pData->buffer, str.pData->length );
1383         return (ret < 0 ? ret : ret+fromIndex);
1384     }
1385 #endif
1386     /**
1387      @overload
1388      This function accepts an ASCII string literal as its argument.
1389      @since LibreOffice 3.6
1390     */
1391     template< typename T >
indexOf(T & literal,sal_Int32 fromIndex=0) const1392     typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const
1393     {
1394         RTL_STRING_CONST_FUNCTION
1395         assert(
1396             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1397         sal_Int32 n = rtl_str_indexOfStr_WithLength(
1398             pData->buffer + fromIndex, pData->length - fromIndex,
1399             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
1400             libreoffice_internal::ConstCharArrayDetector<T>::length);
1401         return n < 0 ? n : n + fromIndex;
1402     }
1403 
1404     /**
1405       Returns the index within this string of the first occurrence of the
1406       specified substring, starting at the specified index.
1407 
1408       If str doesn't include any character, always -1 is
1409       returned. This is also the case, if both strings are empty.
1410 
1411       @param    str         the substring to search for.
1412       @param    len         the length of the substring.
1413       @param    fromIndex   the index to start the search from.
1414       @return   If the string argument occurs one or more times as a substring
1415                 within this string at the starting index, then the index
1416                 of the first character of the first such substring is
1417                 returned. If it does not occur as a substring starting
1418                 at fromIndex or beyond, -1 is returned.
1419 
1420       @since LibreOffice 3.6
1421     */
indexOfL(char const * str,sal_Int32 len,sal_Int32 fromIndex=0) const1422     sal_Int32 indexOfL(char const * str, sal_Int32 len, sal_Int32 fromIndex = 0)
1423         const
1424     {
1425         sal_Int32 n = rtl_str_indexOfStr_WithLength(
1426             pData->buffer + fromIndex, pData->length - fromIndex, str, len);
1427         return n < 0 ? n : n + fromIndex;
1428     }
1429 
1430     // This overload is left undefined, to detect calls of indexOfL that
1431     // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
1432     // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
1433     // platforms):
1434 #if SAL_TYPES_SIZEOFLONG == 8
1435     void indexOfL(char const *, sal_Int32, rtl_TextEncoding) const;
1436 #endif
1437 
1438     /**
1439       Returns the index within this string of the last occurrence of
1440       the specified substring, searching backward starting at the end.
1441 
1442       The returned index indicates the starting index of the substring
1443       in this string.
1444       If str doesn't include any character, always -1 is
1445       returned. This is also the case, if both strings are empty.
1446 
1447       @param    str         the substring to search for.
1448       @return   If the string argument occurs one or more times as a substring
1449                 within this string, then the index of the first character of
1450                 the last such substring is returned. If it does not occur as
1451                 a substring, -1 is returned.
1452     */
1453 #if defined LIBO_INTERNAL_ONLY
lastIndexOf(std::string_view str) const1454     sal_Int32 lastIndexOf( std::string_view str ) const
1455     {
1456         return rtl_str_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1457                                                   str.data(), str.size() );
1458     }
1459 #else
lastIndexOf(const OString & str) const1460     sal_Int32 lastIndexOf( const OString & str ) const
1461     {
1462         return rtl_str_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1463                                                   str.pData->buffer, str.pData->length );
1464     }
1465 #endif
1466 
1467     /**
1468       Returns the index within this string of the last occurrence of
1469       the specified substring, searching backward starting before the specified
1470       index.
1471 
1472       The returned index indicates the starting index of the substring
1473       in this string.
1474       If str doesn't include any character, always -1 is
1475       returned. This is also the case, if both strings are empty.
1476 
1477       @param    str         the substring to search for.
1478       @param    fromIndex   the index before which to start the search.
1479       @return   If the string argument occurs one or more times as a substring
1480                 within this string before the starting index, then the index
1481                 of the first character of the last such substring is
1482                 returned. Otherwise, -1 is returned.
1483     */
1484 #if defined LIBO_INTERNAL_ONLY
lastIndexOf(std::string_view str,sal_Int32 fromIndex) const1485     sal_Int32 lastIndexOf( std::string_view str, sal_Int32 fromIndex ) const
1486     {
1487         return rtl_str_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1488                                                   str.data(), str.size() );
1489     }
1490 #else
lastIndexOf(const OString & str,sal_Int32 fromIndex) const1491     sal_Int32 lastIndexOf( const OString & str, sal_Int32 fromIndex ) const
1492     {
1493         return rtl_str_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1494                                                   str.pData->buffer, str.pData->length );
1495     }
1496 #endif
1497 
1498     /**
1499       Returns a new string that is a substring of this string.
1500 
1501       The substring begins at the specified beginIndex. If
1502       beginIndex is negative or be greater than the length of
1503       this string, behaviour is undefined.
1504 
1505       @param     beginIndex   the beginning index, inclusive.
1506       @return    the specified substring.
1507     */
copy(sal_Int32 beginIndex) const1508     SAL_WARN_UNUSED_RESULT OString copy( sal_Int32 beginIndex ) const
1509     {
1510         return copy(beginIndex, getLength() - beginIndex);
1511     }
1512 
1513     /**
1514       Returns a new string that is a substring of this string.
1515 
1516       The substring begins at the specified beginIndex and contains count
1517       characters.  If either beginIndex or count are negative,
1518       or beginIndex + count are greater than the length of this string
1519       then behaviour is undefined.
1520 
1521       @param     beginIndex   the beginning index, inclusive.
1522       @param     count        the number of characters.
1523       @return    the specified substring.
1524     */
copy(sal_Int32 beginIndex,sal_Int32 count) const1525     SAL_WARN_UNUSED_RESULT OString copy( sal_Int32 beginIndex, sal_Int32 count ) const
1526     {
1527         rtl_String *pNew = NULL;
1528         rtl_string_newFromSubString( &pNew, pData, beginIndex, count );
1529         return OString( pNew, SAL_NO_ACQUIRE );
1530     }
1531 
1532 #if defined LIBO_INTERNAL_ONLY
1533     /**
1534       Returns a std::string_view that is a view of a substring of this string.
1535 
1536       The substring begins at the specified beginIndex. If
1537       beginIndex is negative or be greater than the length of
1538       this string, behaviour is undefined.
1539 
1540       @param     beginIndex   the beginning index, inclusive.
1541       @return    the specified substring.
1542     */
subView(sal_Int32 beginIndex) const1543     SAL_WARN_UNUSED_RESULT std::string_view subView( sal_Int32 beginIndex ) const
1544     {
1545         assert(beginIndex >= 0);
1546         assert(beginIndex <= getLength());
1547         return subView(beginIndex, getLength() - beginIndex);
1548     }
1549 
1550     /**
1551       Returns a std::string_view that is a view of a substring of this string.
1552 
1553       The substring begins at the specified beginIndex and contains count
1554       characters.  If either beginIndex or count are negative,
1555       or beginIndex + count are greater than the length of this string
1556       then behaviour is undefined.
1557 
1558       @param     beginIndex   the beginning index, inclusive.
1559       @param     count        the number of characters.
1560       @return    the specified substring.
1561     */
subView(sal_Int32 beginIndex,sal_Int32 count) const1562     SAL_WARN_UNUSED_RESULT std::string_view subView( sal_Int32 beginIndex, sal_Int32 count ) const
1563     {
1564         assert(beginIndex >= 0);
1565         assert(count >= 0);
1566         assert(beginIndex <= getLength());
1567         assert(count <= getLength() - beginIndex);
1568         return std::string_view(*this).substr(beginIndex, count);
1569     }
1570 #endif
1571 
1572 #ifndef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
1573     /**
1574       Concatenates the specified string to the end of this string.
1575 
1576       @param    str   the string that is concatenated to the end
1577                       of this string.
1578       @return   a string that represents the concatenation of this string
1579                 followed by the string argument.
1580     */
concat(const OString & str) const1581     SAL_WARN_UNUSED_RESULT OString concat( const OString & str ) const
1582     {
1583         rtl_String* pNew = NULL;
1584         rtl_string_newConcat( &pNew, pData, str.pData );
1585         return OString( pNew, SAL_NO_ACQUIRE );
1586     }
1587 #endif
1588 
1589 #ifndef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
operator +(const OString & str1,const OString & str2)1590     friend OString operator+( const OString & str1, const OString & str2  )
1591     {
1592         return str1.concat( str2 );
1593     }
1594 #endif
1595 
1596     /**
1597       Returns a new string resulting from replacing n = count characters
1598       from position index in this string with newStr.
1599 
1600       @param  index   the replacing index in str.
1601                       The index must be greater or equal as 0 and
1602                       less or equal as the length of the string.
1603       @param  count   the count of characters that will replaced
1604                       The count must be greater or equal as 0 and
1605                       less or equal as the length of the string minus index.
1606       @param  newStr  the new substring.
1607       @return the new string.
1608     */
replaceAt(sal_Int32 index,sal_Int32 count,const OString & newStr) const1609     SAL_WARN_UNUSED_RESULT OString replaceAt( sal_Int32 index, sal_Int32 count, const OString& newStr ) const
1610     {
1611         rtl_String* pNew = NULL;
1612         rtl_string_newReplaceStrAt( &pNew, pData, index, count, newStr.pData );
1613         return OString( pNew, SAL_NO_ACQUIRE );
1614     }
1615 
1616     /**
1617       Returns a new string resulting from replacing all occurrences of
1618       oldChar in this string with newChar.
1619 
1620       If the character oldChar does not occur in the character sequence
1621       represented by this object, then the string is assigned with
1622       str.
1623 
1624       @param    oldChar     the old character.
1625       @param    newChar     the new character.
1626       @return   a string derived from this string by replacing every
1627                 occurrence of oldChar with newChar.
1628     */
replace(char oldChar,char newChar) const1629     SAL_WARN_UNUSED_RESULT OString replace( char oldChar, char newChar ) const
1630     {
1631         rtl_String* pNew = NULL;
1632         rtl_string_newReplace( &pNew, pData, oldChar, newChar );
1633         return OString( pNew, SAL_NO_ACQUIRE );
1634     }
1635 
1636     /**
1637       Returns a new string resulting from replacing the first occurrence of a
1638       given substring with another substring.
1639 
1640       @param from  the substring to be replaced
1641 
1642       @param to  the replacing substring
1643 
1644       @param[in,out] index  pointer to a start index; if the pointer is
1645       non-null: upon entry to the function, its value is the index into the this
1646       string at which to start searching for the \p from substring, the value
1647       must be non-negative and not greater than this string's length; upon exit
1648       from the function its value is the index into this string at which the
1649       replacement took place or -1 if no replacement took place; if the pointer
1650       is null, searching always starts at index 0
1651 
1652       @since LibreOffice 3.6
1653     */
replaceFirst(OString const & from,OString const & to,sal_Int32 * index=NULL) const1654     SAL_WARN_UNUSED_RESULT OString replaceFirst(
1655         OString const & from, OString const & to, sal_Int32 * index = NULL) const
1656     {
1657         rtl_String * s = NULL;
1658         sal_Int32 i = 0;
1659         rtl_string_newReplaceFirst(
1660             &s, pData, from.pData->buffer, from.pData->length,
1661             to.pData->buffer, to.pData->length, index == NULL ? &i : index);
1662         return OString(s, SAL_NO_ACQUIRE);
1663     }
1664 
1665     /**
1666       Returns a new string resulting from replacing all occurrences of a given
1667       substring with another substring.
1668 
1669       Replacing subsequent occurrences picks up only after a given replacement.
1670       That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
1671 
1672       @param from  the substring to be replaced
1673 
1674       @param to  the replacing substring
1675 
1676       @since LibreOffice 3.6
1677     */
replaceAll(OString const & from,OString const & to) const1678     SAL_WARN_UNUSED_RESULT OString replaceAll(OString const & from, OString const & to) const {
1679         rtl_String * s = NULL;
1680         rtl_string_newReplaceAll(
1681             &s, pData, from.pData->buffer, from.pData->length,
1682             to.pData->buffer, to.pData->length);
1683         return OString(s, SAL_NO_ACQUIRE);
1684     }
1685 
1686     /**
1687       Converts from this string all ASCII uppercase characters (65-90)
1688       to ASCII lowercase characters (97-122).
1689 
1690       This function can't be used for language specific conversion.
1691       If the string doesn't contain characters which must be converted,
1692       then the new string is assigned with str.
1693 
1694       @return   the string, converted to ASCII lowercase.
1695     */
toAsciiLowerCase() const1696     SAL_WARN_UNUSED_RESULT OString toAsciiLowerCase() const
1697     {
1698         rtl_String* pNew = NULL;
1699         rtl_string_newToAsciiLowerCase( &pNew, pData );
1700         return OString( pNew, SAL_NO_ACQUIRE );
1701     }
1702 
1703     /**
1704       Converts from this string all ASCII lowercase characters (97-122)
1705       to ASCII uppercase characters (65-90).
1706 
1707       This function can't be used for language specific conversion.
1708       If the string doesn't contain characters which must be converted,
1709       then the new string is assigned with str.
1710 
1711       @return   the string, converted to ASCII uppercase.
1712     */
toAsciiUpperCase() const1713     SAL_WARN_UNUSED_RESULT OString toAsciiUpperCase() const
1714     {
1715         rtl_String* pNew = NULL;
1716         rtl_string_newToAsciiUpperCase( &pNew, pData );
1717         return OString( pNew, SAL_NO_ACQUIRE );
1718     }
1719 
1720     /**
1721       Returns a new string resulting from removing white space from both ends
1722       of the string.
1723 
1724       All characters that have codes less than or equal to
1725       32 (the space character) are considered to be white space.
1726       If the string doesn't contain white spaces at both ends,
1727       then the new string is assigned with str.
1728 
1729       @return   the string, with white space removed from the front and end.
1730     */
trim() const1731     SAL_WARN_UNUSED_RESULT OString trim() const
1732     {
1733         rtl_String* pNew = NULL;
1734         rtl_string_newTrim( &pNew, pData );
1735         return OString( pNew, SAL_NO_ACQUIRE );
1736     }
1737 
1738     /**
1739       Returns a token in the string.
1740 
1741       Example:
1742         sal_Int32 nIndex = 0;
1743         do
1744         {
1745             ...
1746             OString aToken = aStr.getToken( 0, ';', nIndex );
1747             ...
1748         }
1749         while ( nIndex >= 0 );
1750 
1751       @param    token       the number of the token to return.
1752       @param    cTok        the character which separate the tokens.
1753       @param    index       the position at which the token is searched in the
1754                             string.
1755                             The index must not be greater than the length of the
1756                             string.
1757                             This param is set to the position of the
1758                             next token or to -1, if it is the last token.
1759       @return   the token; if either token or index is negative, an empty token
1760                 is returned (and index is set to -1)
1761     */
getToken(sal_Int32 token,char cTok,sal_Int32 & index) const1762     OString getToken( sal_Int32 token, char cTok, sal_Int32& index ) const
1763     {
1764         rtl_String * pNew = NULL;
1765         index = rtl_string_getToken( &pNew, pData, token, cTok, index );
1766         return OString( pNew, SAL_NO_ACQUIRE );
1767     }
1768 
1769     /**
1770       Returns a token from the string.
1771 
1772       The same as getToken(sal_Int32, char, sal_Int32 &), but always passing
1773       in 0 as the start index in the third argument.
1774 
1775       @param count  the number of the token to return, starting with 0
1776       @param separator  the character which separates the tokens
1777 
1778       @return  the given token, or an empty string
1779 
1780       @since LibreOffice 3.6
1781      */
getToken(sal_Int32 count,char separator) const1782     OString getToken(sal_Int32 count, char separator) const {
1783         sal_Int32 n = 0;
1784         return getToken(count, separator, n);
1785     }
1786 
1787     /**
1788       Returns the Boolean value from this string.
1789 
1790       This function can't be used for language specific conversion.
1791 
1792       @return   true, if the string is 1 or "True" in any ASCII case.
1793                 false in any other case.
1794     */
toBoolean() const1795     bool toBoolean() const
1796     {
1797         return rtl_str_toBoolean( pData->buffer );
1798     }
1799 
1800     /**
1801       Returns the first character from this string.
1802 
1803       @return   the first character from this string or 0, if this string
1804                 is empty.
1805     */
toChar() const1806     char toChar() const
1807     {
1808         return pData->buffer[0];
1809     }
1810 
1811     /**
1812       Returns the int32 value from this string.
1813 
1814       This function can't be used for language specific conversion.
1815 
1816       @param    radix       the radix (between 2 and 36)
1817       @return   the int32 represented from this string.
1818                 0 if this string represents no number or one of too large
1819                 magnitude.
1820     */
toInt32(sal_Int16 radix=10) const1821     sal_Int32 toInt32( sal_Int16 radix = 10 ) const
1822     {
1823         return rtl_str_toInt32( pData->buffer, radix );
1824     }
1825 
1826     /**
1827       Returns the uint32 value from this string.
1828 
1829       This function can't be used for language specific conversion.
1830 
1831       @param    radix       the radix (between 2 and 36)
1832       @return   the uint32 represented from this string.
1833                 0 if this string represents no number or one of too large
1834                 magnitude.
1835 
1836       @since LibreOffice 4.2
1837     */
toUInt32(sal_Int16 radix=10) const1838     sal_uInt32 toUInt32( sal_Int16 radix = 10 ) const
1839     {
1840         return rtl_str_toUInt32( pData->buffer, radix );
1841     }
1842 
1843     /**
1844       Returns the int64 value from this string.
1845 
1846       This function can't be used for language specific conversion.
1847 
1848       @param    radix       the radix (between 2 and 36)
1849       @return   the int64 represented from this string.
1850                 0 if this string represents no number or one of too large
1851                 magnitude.
1852     */
toInt64(sal_Int16 radix=10) const1853     sal_Int64 toInt64( sal_Int16 radix = 10 ) const
1854     {
1855         return rtl_str_toInt64( pData->buffer, radix );
1856     }
1857 
1858     /**
1859       Returns the uint64 value from this string.
1860 
1861       This function can't be used for language specific conversion.
1862 
1863       @param    radix       the radix (between 2 and 36)
1864       @return   the uint64 represented from this string.
1865                 0 if this string represents no number or one of too large
1866                 magnitude.
1867 
1868       @since LibreOffice 4.1
1869     */
toUInt64(sal_Int16 radix=10) const1870     sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const
1871     {
1872         return rtl_str_toUInt64( pData->buffer, radix );
1873     }
1874 
1875     /**
1876       Returns the float value from this string.
1877 
1878       This function can't be used for language specific conversion.
1879 
1880       @return   the float represented from this string.
1881                 0.0 if this string represents no number.
1882     */
toFloat() const1883     float toFloat() const
1884     {
1885         return rtl_str_toFloat( pData->buffer );
1886     }
1887 
1888     /**
1889       Returns the double value from this string.
1890 
1891       This function can't be used for language specific conversion.
1892 
1893       @return   the double represented from this string.
1894                 0.0 if this string represents no number.
1895     */
toDouble() const1896     double toDouble() const
1897     {
1898         return rtl_str_toDouble( pData->buffer );
1899     }
1900 
1901 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
1902 
number(int i,sal_Int16 radix=10)1903     static OStringNumber< int > number( int i, sal_Int16 radix = 10 )
1904     {
1905         return OStringNumber< int >( i, radix );
1906     }
number(long long ll,sal_Int16 radix=10)1907     static OStringNumber< long long > number( long long ll, sal_Int16 radix = 10 )
1908     {
1909         return OStringNumber< long long >( ll, radix );
1910     }
number(unsigned long long ll,sal_Int16 radix=10)1911     static OStringNumber< unsigned long long > number( unsigned long long ll, sal_Int16 radix = 10 )
1912     {
1913         return OStringNumber< unsigned long long >( ll, radix );
1914     }
number(unsigned int i,sal_Int16 radix=10)1915     static OStringNumber< unsigned long long > number( unsigned int i, sal_Int16 radix = 10 )
1916     {
1917         return number( static_cast< unsigned long long >( i ), radix );
1918     }
number(long i,sal_Int16 radix=10)1919     static OStringNumber< long long > number( long i, sal_Int16 radix = 10)
1920     {
1921         return number( static_cast< long long >( i ), radix );
1922     }
number(unsigned long i,sal_Int16 radix=10)1923     static OStringNumber< unsigned long long > number( unsigned long i, sal_Int16 radix = 10 )
1924     {
1925         return number( static_cast< unsigned long long >( i ), radix );
1926     }
number(float f)1927     static OStringNumber< float > number( float f )
1928     {
1929         return OStringNumber< float >( f );
1930     }
number(double d)1931     static OStringNumber< double > number( double d )
1932     {
1933         return OStringNumber< double >( d );
1934     }
1935 #else
1936     /**
1937       Returns the string representation of the integer argument.
1938 
1939       This function can't be used for language specific conversion.
1940 
1941       @param    i           an integer value
1942       @param    radix       the radix (between 2 and 36)
1943       @return   a string with the string representation of the argument.
1944       @since LibreOffice 4.1
1945     */
number(int i,sal_Int16 radix=10)1946     static OString number( int i, sal_Int16 radix = 10 )
1947     {
1948         char aBuf[RTL_STR_MAX_VALUEOFINT32];
1949         return OString(aBuf, rtl_str_valueOfInt32(aBuf, i, radix));
1950     }
1951     /// @overload
1952     /// @since LibreOffice 4.1
number(unsigned int i,sal_Int16 radix=10)1953     static OString number( unsigned int i, sal_Int16 radix = 10 )
1954     {
1955         return number( static_cast< unsigned long long >( i ), radix );
1956     }
1957     /// @overload
1958     /// @since LibreOffice 4.1
number(long i,sal_Int16 radix=10)1959     static OString number( long i, sal_Int16 radix = 10 )
1960     {
1961         return number( static_cast< long long >( i ), radix );
1962     }
1963     /// @overload
1964     /// @since LibreOffice 4.1
number(unsigned long i,sal_Int16 radix=10)1965     static OString number( unsigned long i, sal_Int16 radix = 10 )
1966     {
1967         return number( static_cast< unsigned long long >( i ), radix );
1968     }
1969     /// @overload
1970     /// @since LibreOffice 4.1
number(long long ll,sal_Int16 radix=10)1971     static OString number( long long ll, sal_Int16 radix = 10 )
1972     {
1973         char aBuf[RTL_STR_MAX_VALUEOFINT64];
1974         return OString(aBuf, rtl_str_valueOfInt64(aBuf, ll, radix));
1975     }
1976     /// @overload
1977     /// @since LibreOffice 4.1
number(unsigned long long ll,sal_Int16 radix=10)1978     static OString number( unsigned long long ll, sal_Int16 radix = 10 )
1979     {
1980         char aBuf[RTL_STR_MAX_VALUEOFUINT64];
1981         return OString(aBuf, rtl_str_valueOfUInt64(aBuf, ll, radix));
1982     }
1983 
1984     /**
1985       Returns the string representation of the float argument.
1986 
1987       This function can't be used for language specific conversion.
1988 
1989       @param    f           a float.
1990       @return   a string with the decimal representation of the argument.
1991       @since LibreOffice 4.1
1992     */
number(float f)1993     static OString number( float f )
1994     {
1995         char aBuf[RTL_STR_MAX_VALUEOFFLOAT];
1996         return OString(aBuf, rtl_str_valueOfFloat(aBuf, f));
1997     }
1998 
1999     /**
2000       Returns the string representation of the double argument.
2001 
2002       This function can't be used for language specific conversion.
2003 
2004       @param    d           a double.
2005       @return   a string with the decimal representation of the argument.
2006       @since LibreOffice 4.1
2007     */
number(double d)2008     static OString number( double d )
2009     {
2010         char aBuf[RTL_STR_MAX_VALUEOFDOUBLE];
2011         return OString(aBuf, rtl_str_valueOfDouble(aBuf, d));
2012     }
2013 #endif
2014 
2015     /**
2016       Returns the string representation of the sal_Bool argument.
2017 
2018       If the sal_Bool is true, the string "true" is returned.
2019       If the sal_Bool is false, the string "false" is returned.
2020       This function can't be used for language specific conversion.
2021 
2022       @param    b   a sal_Bool.
2023       @return   a string with the string representation of the argument.
2024       @deprecated use boolean()
2025     */
valueOf(sal_Bool b)2026     SAL_DEPRECATED("use boolean()") static OString valueOf( sal_Bool b )
2027     {
2028         return boolean(b);
2029     }
2030 
2031     /**
2032       Returns the string representation of the boolean argument.
2033 
2034       If the argument is true, the string "true" is returned.
2035       If the argument is false, the string "false" is returned.
2036       This function can't be used for language specific conversion.
2037 
2038       @param    b   a bool.
2039       @return   a string with the string representation of the argument.
2040       @since LibreOffice 4.1
2041     */
boolean(bool b)2042     static OString boolean( bool b )
2043     {
2044         char aBuf[RTL_STR_MAX_VALUEOFBOOLEAN];
2045         return OString(aBuf, rtl_str_valueOfBoolean(aBuf, b));
2046     }
2047 
2048     /**
2049       Returns the string representation of the char argument.
2050 
2051       @param    c   a character.
2052       @return   a string with the string representation of the argument.
2053       @deprecated use operator, function or constructor taking char or sal_Unicode argument
2054     */
valueOf(char c)2055     SAL_DEPRECATED("convert to OString or use directly") static OString valueOf( char c )
2056     {
2057         return OString( &c, 1 );
2058     }
2059 
2060     /**
2061       Returns the string representation of the int argument.
2062 
2063       This function can't be used for language specific conversion.
2064 
2065       @param    i           a int32.
2066       @param    radix       the radix (between 2 and 36)
2067       @return   a string with the string representation of the argument.
2068       @deprecated use number()
2069     */
valueOf(sal_Int32 i,sal_Int16 radix=10)2070     SAL_DEPRECATED("use number()") static OString valueOf( sal_Int32 i, sal_Int16 radix = 10 )
2071     {
2072         return number( i, radix );
2073     }
2074 
2075     /**
2076       Returns the string representation of the long argument.
2077 
2078       This function can't be used for language specific conversion.
2079 
2080       @param    ll          a int64.
2081       @param    radix       the radix (between 2 and 36)
2082       @return   a string with the string representation of the argument.
2083       @deprecated use number()
2084     */
valueOf(sal_Int64 ll,sal_Int16 radix=10)2085     SAL_DEPRECATED("use number()") static OString valueOf( sal_Int64 ll, sal_Int16 radix = 10 )
2086     {
2087         return number( ll, radix );
2088     }
2089 
2090     /**
2091       Returns the string representation of the float argument.
2092 
2093       This function can't be used for language specific conversion.
2094 
2095       @param    f           a float.
2096       @return   a string with the string representation of the argument.
2097       @deprecated use number()
2098     */
valueOf(float f)2099     SAL_DEPRECATED("use number()") static OString valueOf( float f )
2100     {
2101         return number(f);
2102     }
2103 
2104     /**
2105       Returns the string representation of the double argument.
2106 
2107       This function can't be used for language specific conversion.
2108 
2109       @param    d           a double.
2110       @return   a string with the string representation of the argument.
2111       @deprecated use number()
2112     */
valueOf(double d)2113     SAL_DEPRECATED("use number()") static OString valueOf( double d )
2114     {
2115         return number(d);
2116     }
2117 
2118 #if defined LIBO_INTERNAL_ONLY
operator std::string_view() const2119     operator std::string_view() const { return {getStr(), sal_uInt32(getLength())}; }
2120 #endif
2121 
2122 #if defined LIBO_INTERNAL_ONLY
2123     // A wrapper for the first expression in an
2124     //
2125     //   OString::Concat(e1) + e2 + ...
2126     //
2127     // concatenation chain, when neither of the first two e1, e2 is one of our rtl string-related
2128     // classes (so something like
2129     //
2130     //   OString s = "a" + (b ? std::string_view("c") : std::string_view("dd"));
2131     //
2132     // would not compile):
2133     template<typename T> [[nodiscard]] static
2134     typename std::enable_if_t<
2135         ToStringHelper<T>::allowOStringConcat, OStringConcat<OStringConcatMarker, T>>
Concat(T const & value)2136     Concat(T const & value) { return OStringConcat<OStringConcatMarker, T>({}, value); }
2137 
2138     // This overload is needed so that an argument of type 'char const[N]' ends up as
2139     // 'OStringConcat<rtl::OStringConcatMarker, char const[N]>' rather than as
2140     // 'OStringConcat<rtl::OStringConcatMarker, char[N]>':
2141     template<typename T, std::size_t N> [[nodiscard]] static
2142     typename std::enable_if_t<
2143         ToStringHelper<T[N]>::allowOStringConcat, OStringConcat<OStringConcatMarker, T[N]>>
Concat(T (& value)[N])2144     Concat(T (& value)[N]) { return OStringConcat<OStringConcatMarker, T[N]>({}, value); }
2145 #endif
2146 };
2147 
2148 /* ======================================================================= */
2149 
2150 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
2151 
2152 /**
2153  @internal
2154 */
2155 template<>
2156 struct ToStringHelper< OString >
2157     {
lengthrtl::ToStringHelper2158     static std::size_t length( const OString& s ) { return s.getLength(); }
addDatartl::ToStringHelper2159     static char* addData( char* buffer, const OString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
2160     static const bool allowOStringConcat = true;
2161     static const bool allowOUStringConcat = false;
2162     };
2163 
2164 /**
2165  @internal
2166 */
2167 template<std::size_t N>
2168 struct ToStringHelper< OStringLiteral<N> >
2169     {
lengthrtl::ToStringHelper2170     static constexpr std::size_t length( const OStringLiteral<N>& str ) { return str.getLength(); }
addDatartl::ToStringHelper2171     static char* addData( char* buffer, const OStringLiteral<N>& str ) { return addDataHelper( buffer, str.getStr(), str.getLength() ); }
2172     static const bool allowOStringConcat = true;
2173     static const bool allowOUStringConcat = false;
2174     };
2175 
2176 /**
2177  @internal
2178 */
2179 template< typename charT, typename traits, typename T1, typename T2 >
operator <<(std::basic_ostream<charT,traits> & stream,OStringConcat<T1,T2> && concat)2180 inline std::basic_ostream<charT, traits> & operator <<(
2181     std::basic_ostream<charT, traits> & stream, OStringConcat< T1, T2 >&& concat)
2182 {
2183     return stream << OString( std::move(concat) );
2184 }
2185 #endif
2186 
2187 
2188 /** A helper to use OStrings with hash maps.
2189 
2190     Instances of this class are unary function objects that can be used as
2191     hash function arguments to std::unordered_map and similar constructs.
2192  */
2193 struct OStringHash
2194 {
2195     /** Compute a hash code for a string.
2196 
2197         @param rString
2198         a string.
2199 
2200         @return
2201         a hash code for the string.  This hash code should not be stored
2202         persistently, as its computation may change in later revisions.
2203      */
operator ()rtl::OStringHash2204     size_t operator()( const OString& rString ) const
2205         { return static_cast<size_t>(rString.hashCode()); }
2206 };
2207 
2208 /** Equality functor for classic c-strings (i.e., null-terminated char* strings). */
2209 struct CStringEqual
2210 {
operator ()rtl::CStringEqual2211     bool operator()( const char* p1, const char* p2) const
2212         { return rtl_str_compare(p1, p2) == 0; }
2213 };
2214 
2215 /** Hashing functor for classic c-strings (i.e., null-terminated char* strings). */
2216 struct CStringHash
2217 {
operator ()rtl::CStringHash2218     size_t operator()(const char* p) const
2219         { return rtl_str_hashCode(p); }
2220 };
2221 
2222 /* ======================================================================= */
2223 
2224 /**
2225     Support for rtl::OString in std::ostream (and thus in
2226     CPPUNIT_ASSERT or SAL_INFO macros, for example).
2227 
2228     @since LibreOffice 4.0
2229  */
2230 template< typename charT, typename traits > std::basic_ostream<charT, traits> &
operator <<(std::basic_ostream<charT,traits> & stream,OString const & rString)2231 operator <<(
2232     std::basic_ostream<charT, traits> & stream, OString const & rString)
2233 {
2234     return stream << rString.getStr();
2235         // best effort; potentially loses data due to embedded null characters
2236 }
2237 
2238 } /* Namespace */
2239 
2240 #ifdef RTL_STRING_UNITTEST
2241 namespace rtl
2242 {
2243 typedef rtlunittest::OString OString;
2244 }
2245 #undef RTL_STRING_CONST_FUNCTION
2246 #endif
2247 
2248 #if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
2249 using ::rtl::OString;
2250 using ::rtl::OStringChar;
2251 using ::rtl::OStringHash;
2252 using ::rtl::OStringLiteral;
2253 #endif
2254 
2255 /// @cond INTERNAL
2256 /**
2257   Make OString hashable by default for use in STL containers.
2258 
2259   @since LibreOffice 6.0
2260 */
2261 #if defined LIBO_INTERNAL_ONLY
2262 namespace std {
2263 
2264 template<>
2265 struct hash<::rtl::OString>
2266 {
operator ()std::hash2267     std::size_t operator()(::rtl::OString const & s) const
2268     { return std::size_t(s.hashCode()); }
2269 };
2270 
2271 }
2272 
2273 #endif
2274 /// @endcond
2275 
2276 #endif // INCLUDED_RTL_STRING_HXX
2277 
2278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2279