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_USTRBUF_HXX
25 #define INCLUDED_RTL_USTRBUF_HXX
26 
27 #include "sal/config.h"
28 
29 #include <cassert>
30 #include <cstring>
31 #include <limits>
32 #include <new>
33 
34 #if defined LIBO_INTERNAL_ONLY
35 #include <string_view>
36 #endif
37 
38 #include "rtl/ustrbuf.h"
39 #include "rtl/ustring.hxx"
40 #include "rtl/stringutils.hxx"
41 #include "sal/types.h"
42 
43 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
44 #include "rtl/stringconcat.hxx"
45 #endif
46 
47 #ifdef RTL_STRING_UNITTEST
48 extern bool rtl_string_unittest_invalid_conversion;
49 #endif
50 
51 // The unittest uses slightly different code to help check that the proper
52 // calls are made. The class is put into a different namespace to make
53 // sure the compiler generates a different (if generating also non-inline)
54 // copy of the function and does not merge them together. The class
55 // is "brought" into the proper rtl namespace by a typedef below.
56 #ifdef RTL_STRING_UNITTEST
57 #define rtl rtlunittest
58 #endif
59 
60 namespace rtl
61 {
62 
63 #ifdef RTL_STRING_UNITTEST
64 #undef rtl
65 #endif
66 
67 /** A string buffer implements a mutable sequence of characters.
68  */
69 class SAL_WARN_UNUSED OUStringBuffer
70 {
71 friend class OUString;
72 public:
73     /**
74         Constructs a string buffer with no characters in it and an
75         initial capacity of 16 characters.
76      */
OUStringBuffer()77     OUStringBuffer()
78         : pData(NULL)
79         , nCapacity( 16 )
80     {
81         rtl_uString_new_WithLength( &pData, nCapacity );
82     }
83 
84     /**
85         Allocates a new string buffer that contains the same sequence of
86         characters as the string buffer argument.
87 
88         @param   value   a <code>OUStringBuffer</code>.
89      */
OUStringBuffer(const OUStringBuffer & value)90     OUStringBuffer( const OUStringBuffer & value )
91         : pData(NULL)
92         , nCapacity( value.nCapacity )
93     {
94         rtl_uStringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
95     }
96 
97     /**
98         Constructs a string buffer with no characters in it and an
99         initial capacity specified by the <code>length</code> argument.
100 
101         @param      length   the initial capacity.
102      */
OUStringBuffer(int length)103     explicit OUStringBuffer(int length)
104         : pData(NULL)
105         , nCapacity( length )
106     {
107         rtl_uString_new_WithLength( &pData, length );
108     }
109 #if __cplusplus >= 201103L
OUStringBuffer(unsigned int length)110     explicit OUStringBuffer(unsigned int length)
111         : OUStringBuffer(static_cast<int>(length))
112     {
113     }
114 #if SAL_TYPES_SIZEOFLONG == 4
115     // additional overloads for sal_Int32 sal_uInt32
OUStringBuffer(long length)116     explicit OUStringBuffer(long length)
117         : OUStringBuffer(static_cast<int>(length))
118     {
119     }
OUStringBuffer(unsigned long length)120     explicit OUStringBuffer(unsigned long length)
121         : OUStringBuffer(static_cast<int>(length))
122     {
123     }
124 #endif
125     // avoid obvious bugs
126     explicit OUStringBuffer(char) = delete;
127     explicit OUStringBuffer(sal_Unicode) = delete;
128 #endif
129 
130     /**
131         Constructs a string buffer so that it represents the same
132         sequence of characters as the string argument.
133 
134         The initial
135         capacity of the string buffer is <code>16</code> plus the length
136         of the string argument.
137 
138         @param   value   the initial contents of the buffer.
139      */
140 #if defined LIBO_INTERNAL_ONLY
OUStringBuffer(std::u16string_view sv)141     explicit OUStringBuffer(std::u16string_view sv)
142         : pData(nullptr)
143         , nCapacity( sv.length() + 16 )
144     {
145         if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
146             throw std::bad_alloc();
147         }
148         rtl_uStringbuffer_newFromStr_WithLength( &pData, sv.data(), sv.length() );
149     }
150 #endif
OUStringBuffer(const OUString & value)151     OUStringBuffer(const OUString& value)
152         : pData(NULL)
153         , nCapacity( value.getLength() + 16 )
154     {
155         rtl_uStringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
156     }
157 
158     template< typename T >
OUStringBuffer(T & literal,typename libreoffice_internal::ConstCharArrayDetector<T,libreoffice_internal::Dummy>::Type=libreoffice_internal::Dummy ())159     OUStringBuffer( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
160         : pData(NULL)
161         , nCapacity( libreoffice_internal::ConstCharArrayDetector<T>::length + 16 )
162     {
163         assert(
164             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
165         rtl_uString_newFromLiteral(
166             &pData,
167             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
168             libreoffice_internal::ConstCharArrayDetector<T>::length, 16);
169 #ifdef RTL_STRING_UNITTEST
170         rtl_string_unittest_const_literal = true;
171 #endif
172     }
173 
174 #if defined LIBO_INTERNAL_ONLY
175     /** @overload @since LibreOffice 5.3 */
176     template<typename T>
OUStringBuffer(T & literal,typename libreoffice_internal::ConstCharArrayDetector<T,libreoffice_internal::Dummy>::TypeUtf16=libreoffice_internal::Dummy ())177     OUStringBuffer(
178         T & literal,
179         typename libreoffice_internal::ConstCharArrayDetector<
180             T, libreoffice_internal::Dummy>::TypeUtf16
181                 = libreoffice_internal::Dummy()):
182         pData(nullptr),
183         nCapacity(libreoffice_internal::ConstCharArrayDetector<T>::length + 16)
184     {
185         rtl_uStringbuffer_newFromStr_WithLength(
186             &pData,
187             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
188             libreoffice_internal::ConstCharArrayDetector<T>::length);
189     }
190 
191     /** @overload @since LibreOffice 5.4 */
OUStringBuffer(OUStringLiteral<N> const & literal)192     template<std::size_t N> OUStringBuffer(OUStringLiteral<N> const & literal):
193         pData(nullptr), nCapacity(literal.getLength() + 16) //TODO: check for overflow
194     {
195         rtl_uStringbuffer_newFromStr_WithLength(&pData, literal.getStr(), literal.getLength());
196     }
197 #endif
198 
199 #if defined LIBO_INTERNAL_ONLY && defined RTL_STRING_UNITTEST
200     /// @cond INTERNAL
201     /**
202      * Only used by unittests to detect incorrect conversions.
203      * @internal
204      */
205     template< typename T >
OUStringBuffer(T &,typename libreoffice_internal::ExceptConstCharArrayDetector<T>::Type=libreoffice_internal::Dummy ())206     OUStringBuffer( T&, typename libreoffice_internal::ExceptConstCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
207     {
208         pData = NULL;
209         nCapacity = 10;
210         rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
211         rtl_string_unittest_invalid_conversion = true;
212     }
213     /**
214      * Only used by unittests to detect incorrect conversions.
215      * @internal
216      */
217     template< typename T >
OUStringBuffer(const T &,typename libreoffice_internal::ExceptCharArrayDetector<T>::Type=libreoffice_internal::Dummy ())218     OUStringBuffer( const T&, typename libreoffice_internal::ExceptCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
219     {
220         pData = NULL;
221         nCapacity = 10;
222         rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
223         rtl_string_unittest_invalid_conversion = true;
224     }
225     /// @endcond
226 #endif
227 
228 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
229     /**
230      @overload
231      @internal
232     */
233     template< typename T1, typename T2 >
OUStringBuffer(OUStringConcat<T1,T2> && c)234     OUStringBuffer( OUStringConcat< T1, T2 >&& c )
235     {
236         const sal_Int32 l = c.length();
237         nCapacity = l + 16;
238         pData = rtl_uString_alloc( nCapacity );
239         sal_Unicode* end = c.addData( pData->buffer );
240         *end = '\0';
241         pData->length = l;
242     }
243 
244     /**
245      @overload
246      @internal
247     */
248     template< typename T >
OUStringBuffer(OUStringNumber<T> && n)249     OUStringBuffer( OUStringNumber< T >&& n )
250         : pData(NULL)
251         , nCapacity( n.length + 16 )
252     {
253         rtl_uStringbuffer_newFromStr_WithLength( &pData, n.buf, n.length );
254     }
255 #endif
256 
257 #if defined LIBO_INTERNAL_ONLY
operator std::u16string_view() const258     operator std::u16string_view() const { return {getStr(), sal_uInt32(getLength())}; }
259 #endif
260 
261     /** Assign to this a copy of value.
262      */
operator =(const OUStringBuffer & value)263     OUStringBuffer& operator = ( const OUStringBuffer& value )
264     {
265         if (this != &value)
266         {
267             rtl_uStringbuffer_newFromStringBuffer(&pData,
268                                                   value.nCapacity,
269                                                   value.pData);
270             nCapacity = value.nCapacity;
271         }
272         return *this;
273     }
274 
275     /** Assign from a string.
276 
277         @since LibreOffice 5.3
278     */
279 #if defined LIBO_INTERNAL_ONLY
operator =(std::u16string_view string)280     OUStringBuffer & operator =(std::u16string_view string) {
281         sal_Int32 n = string.length();
282         if (n >= nCapacity) {
283             ensureCapacity(n + 16); //TODO: check for overflow
284         }
285         std::memcpy(
286             pData->buffer, string.data(),
287             (n + 1) * sizeof (sal_Unicode));
288         pData->length = n;
289         return *this;
290     }
291 #endif
operator =(OUString const & string)292     OUStringBuffer & operator =(OUString const & string) {
293         sal_Int32 n = string.getLength();
294         if (n >= nCapacity) {
295             ensureCapacity(n + 16); //TODO: check for overflow
296         }
297         std::memcpy(
298             pData->buffer, string.pData->buffer,
299             (n + 1) * sizeof (sal_Unicode));
300         pData->length = n;
301         return *this;
302     }
303 
304     /** Assign from a string literal.
305 
306         @since LibreOffice 5.3
307     */
308     template<typename T>
309     typename
310         libreoffice_internal::ConstCharArrayDetector<T, OUStringBuffer &>::Type
operator =(T & literal)311     operator =(T & literal) {
312         assert(
313             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
314         sal_Int32 const n
315             = libreoffice_internal::ConstCharArrayDetector<T>::length;
316         if (n >= nCapacity) {
317             ensureCapacity(n + 16); //TODO: check for overflow
318         }
319         char const * from
320             = libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
321                 literal);
322         sal_Unicode * to = pData->buffer;
323         for (sal_Int32 i = 0; i <= n; ++i) {
324             to[i] = from[i];
325         }
326         pData->length = n;
327         return *this;
328     }
329 
330 #if defined LIBO_INTERNAL_ONLY
331     /** @overload @since LibreOffice 5.3 */
332     template<typename T>
333     typename libreoffice_internal::ConstCharArrayDetector<
334         T, OUStringBuffer &>::TypeUtf16
operator =(T & literal)335     operator =(T & literal) {
336         sal_Int32 const n
337             = libreoffice_internal::ConstCharArrayDetector<T>::length;
338         if (n >= nCapacity) {
339             ensureCapacity(n + 16); //TODO: check for overflow
340         }
341         std::memcpy(
342             pData->buffer,
343             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
344             (n + 1) * sizeof (sal_Unicode)); //TODO: check for overflow
345         pData->length = n;
346         return *this;
347     }
348 
349     /** @overload @since LibreOffice 5.4 */
operator =(OUStringLiteral<N> const & literal)350     template<std::size_t N> OUStringBuffer & operator =(OUStringLiteral<N> const & literal) {
351         sal_Int32 const n = literal.getLength();
352         if (n >= nCapacity) {
353             ensureCapacity(n + 16); //TODO: check for overflow
354         }
355         std::memcpy(
356             pData->buffer, literal.getStr(),
357             (n + 1) * sizeof (sal_Unicode)); //TODO: check for overflow
358         pData->length = n;
359         return *this;
360     }
361 #endif
362 
363 #if defined LIBO_INTERNAL_ONLY
364     /** @overload @since LibreOffice 5.3 */
365     template<typename T1, typename T2>
operator =(OUStringConcat<T1,T2> && concat)366     OUStringBuffer & operator =(OUStringConcat<T1, T2> && concat) {
367         sal_Int32 const n = concat.length();
368         if (n >= nCapacity) {
369             ensureCapacity(n + 16); //TODO: check for overflow
370         }
371         *concat.addData(pData->buffer) = 0;
372         pData->length = n;
373         return *this;
374     }
375 
376     /** @overload @internal */
377     template<typename T>
operator =(OUStringNumber<T> && n)378     OUStringBuffer & operator =(OUStringNumber<T> && n)
379     {
380         *this = OUStringBuffer( std::move( n ) );
381         return *this;
382     }
383 #endif
384 
385     /**
386         Release the string data.
387      */
~OUStringBuffer()388     ~OUStringBuffer()
389     {
390         rtl_uString_release( pData );
391     }
392 
393     /**
394         Fill the string data in the new string and clear the buffer.
395 
396         This method is more efficient than the constructor of the string. It does
397         not copy the buffer.
398 
399         @return the string previously contained in the buffer.
400      */
makeStringAndClear()401     SAL_WARN_UNUSED_RESULT OUString makeStringAndClear()
402     {
403         return OUString(
404                   rtl_uStringBuffer_makeStringAndClear( &pData, &nCapacity ),
405                   SAL_NO_ACQUIRE );
406     }
407 
408     /**
409         Returns the length (character count) of this string buffer.
410 
411         @return  the number of characters in this string buffer.
412      */
getLength() const413     sal_Int32 getLength() const
414     {
415         return pData->length;
416     }
417 
418     /**
419       Checks if a string buffer is empty.
420 
421       @return   true if the string buffer is empty;
422                 false, otherwise.
423 
424       @since LibreOffice 4.1
425     */
isEmpty() const426     bool isEmpty() const
427     {
428         return pData->length == 0;
429     }
430 
431     /**
432         Returns the current capacity of the String buffer.
433 
434         The capacity
435         is the amount of storage available for newly inserted
436         characters. The real buffer size is 2 bytes longer, because
437         all strings are 0 terminated.
438 
439         @return  the current capacity of this string buffer.
440      */
getCapacity() const441     sal_Int32 getCapacity() const
442     {
443         return nCapacity;
444     }
445 
446     /**
447         Ensures that the capacity of the buffer is at least equal to the
448         specified minimum.
449 
450         The new capacity will be at least as large as the maximum of the current
451         length (so that no contents of the buffer is destroyed) and the given
452         minimumCapacity.  If the given minimumCapacity is negative, nothing is
453         changed.
454 
455         @param   minimumCapacity   the minimum desired capacity.
456      */
ensureCapacity(sal_Int32 minimumCapacity)457     void ensureCapacity(sal_Int32 minimumCapacity)
458     {
459         rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
460     }
461 
462     /**
463         Sets the length of this String buffer.
464 
465         If the <code>newLength</code> argument is less than the current
466         length of the string buffer, the string buffer is truncated to
467         contain exactly the number of characters given by the
468         <code>newLength</code> argument.
469         <p>
470         If the <code>newLength</code> argument is greater than or equal
471         to the current length, sufficient null characters
472         (<code>'&#92;u0000'</code>) are appended to the string buffer so that
473         length becomes the <code>newLength</code> argument.
474         <p>
475         The <code>newLength</code> argument must be greater than or equal
476         to <code>0</code>.
477 
478         @param      newLength   the new length of the buffer.
479      */
setLength(sal_Int32 newLength)480     void setLength(sal_Int32 newLength)
481     {
482         assert(newLength >= 0);
483         // Avoid modifications if pData points to const empty string:
484         if( newLength != pData->length )
485         {
486             if( newLength > nCapacity )
487                 rtl_uStringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
488             else
489                 pData->buffer[newLength] = 0;
490             pData->length = newLength;
491         }
492     }
493 
494     /**
495         Returns the character at a specific index in this string buffer.
496 
497         The first character of a string buffer is at index
498         <code>0</code>, the next at index <code>1</code>, and so on, for
499         array indexing.
500         <p>
501         The index argument must be greater than or equal to
502         <code>0</code>, and less than the length of this string buffer.
503 
504         @param      index   the index of the desired character.
505         @return     the character at the specified index of this string buffer.
506      */
507     SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
charAt(sal_Int32 index) const508     sal_Unicode charAt( sal_Int32 index ) const
509     {
510         assert(index >= 0 && index < pData->length);
511         return pData->buffer[ index ];
512     }
513 
514     /**
515         The character at the specified index of this string buffer is set
516         to <code>ch</code>.
517 
518         The index argument must be greater than or equal to
519         <code>0</code>, and less than the length of this string buffer.
520 
521         @param      index   the index of the character to modify.
522         @param      ch      the new character.
523      */
524     SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
setCharAt(sal_Int32 index,sal_Unicode ch)525     OUStringBuffer & setCharAt(sal_Int32 index, sal_Unicode ch)
526     {
527         assert(index >= 0 && index < pData->length);
528         pData->buffer[ index ] = ch;
529         return *this;
530     }
531 
532     /**
533         Return a null terminated unicode character array.
534      */
getStr() const535     const sal_Unicode*  getStr() const SAL_RETURNS_NONNULL { return pData->buffer; }
536 
537     /**
538       Access to individual characters.
539 
540       @param index must be non-negative and less than length.
541 
542       @return a reference to the character at the given index.
543 
544       @since LibreOffice 3.5
545     */
operator [](sal_Int32 index)546     sal_Unicode & operator [](sal_Int32 index)
547     {
548         assert(index >= 0 && index < pData->length);
549         return pData->buffer[index];
550     }
551 
552     /**
553       Access to individual characters.
554 
555       @param index must be non-negative and less than length.
556 
557       @return a reference to the character at the given index.
558 
559       @since LibreOffice 4.2
560     */
operator [](sal_Int32 index) const561     const sal_Unicode & operator [](sal_Int32 index) const
562     {
563         assert(index >= 0 && index < pData->length);
564         return pData->buffer[index];
565     }
566 
567     /**
568         Return an OUString instance reflecting the current content
569         of this OUStringBuffer.
570      */
toString() const571     OUString toString() const
572     {
573         return OUString(pData->buffer, pData->length);
574     }
575 
576     /**
577         Appends the string to this string buffer.
578 
579         The characters of the <code>OUString</code> argument are appended, in
580         order, to the contents of this string buffer, increasing the
581         length of this string buffer by the length of the argument.
582 
583         @param   str   a string.
584         @return  this string buffer.
585      */
append(const OUString & str)586     OUStringBuffer & append(const OUString &str)
587     {
588         return append( str.getStr(), str.getLength() );
589     }
590 
591 #if defined LIBO_INTERNAL_ONLY
append(std::u16string_view sv)592     OUStringBuffer & append(std::u16string_view sv) {
593         if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
594             throw std::bad_alloc();
595         }
596         return append(sv.data(), sv.size());
597     }
598 #endif
599 
600     /**
601         Appends the content of a stringbuffer to this string buffer.
602 
603         The characters of the <code>OUStringBuffer</code> argument are appended, in
604         order, to the contents of this string buffer, increasing the
605         length of this string buffer by the length of the argument.
606 
607         @param   str   a string.
608         @return  this string buffer.
609 
610         @since LibreOffice 4.0
611      */
append(const OUStringBuffer & str)612     OUStringBuffer & append(const OUStringBuffer &str)
613     {
614         if(!str.isEmpty())
615         {
616             append( str.getStr(), str.getLength() );
617         }
618         return *this;
619     }
620 
621     /**
622         Appends the string representation of the <code>char</code> array
623         argument to this string buffer.
624 
625         The characters of the array argument are appended, in order, to
626         the contents of this string buffer. The length of this string
627         buffer increases by the length of the argument.
628 
629         @param   str   the characters to be appended.
630         @return  this string buffer.
631      */
632 #if defined LIBO_INTERNAL_ONLY
633     template<typename T>
634     typename libreoffice_internal::CharPtrDetector<T, OUStringBuffer &>::TypeUtf16
append(T const & str)635     append(T const & str)
636 #else
637     OUStringBuffer & append( const sal_Unicode * str )
638 #endif
639     {
640         return append( str, rtl_ustr_getLength( str ) );
641     }
642 
643     /**
644         Appends the string representation of the <code>char</code> array
645         argument to this string buffer.
646 
647         Characters of the character array <code>str</code> are appended,
648         in order, to the contents of this string buffer. The length of this
649         string buffer increases by the value of <code>len</code>.
650 
651         @param str the characters to be appended; must be non-null, and must
652         point to at least len characters
653         @param len the number of characters to append; must be non-negative
654         @return  this string buffer.
655      */
append(const sal_Unicode * str,sal_Int32 len)656     OUStringBuffer & append( const sal_Unicode * str, sal_Int32 len)
657     {
658         assert( len == 0 || str != NULL ); // cannot assert that in rtl_uStringbuffer_insert
659         rtl_uStringbuffer_insert( &pData, &nCapacity, getLength(), str, len );
660         return *this;
661     }
662 
663     /**
664         @overload
665         This function accepts an ASCII string literal as its argument.
666         @since LibreOffice 3.6
667      */
668     template< typename T >
append(T & literal)669     typename libreoffice_internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
670     {
671         assert(
672             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
673         return appendAscii(
674             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
675             libreoffice_internal::ConstCharArrayDetector<T>::length);
676     }
677 
678 #if defined LIBO_INTERNAL_ONLY
679     template<typename T>
680     typename libreoffice_internal::NonConstCharArrayDetector<T, OUStringBuffer &>::TypeUtf16
append(T & value)681     append(T & value) { return append(static_cast<sal_Unicode *>(value)); }
682 
683     /** @overload @since LibreOffice 5.3 */
684     template<typename T>
685     typename libreoffice_internal::ConstCharArrayDetector<
686         T, OUStringBuffer &>::TypeUtf16
append(T & literal)687     append(T & literal) {
688         return append(
689             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
690             libreoffice_internal::ConstCharArrayDetector<T>::length);
691     }
692 
693     /** @overload @since LibreOffice 5.4 */
append(OUStringLiteral<N> const & literal)694     template<std::size_t N> OUStringBuffer & append(OUStringLiteral<N> const & literal) {
695         return append(literal.getStr(), literal.getLength());
696     }
697 #endif
698 
699 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
700     /**
701      @overload
702      @internal
703     */
704     template< typename T1, typename T2 >
append(OUStringConcat<T1,T2> && c)705     OUStringBuffer& append( OUStringConcat< T1, T2 >&& c )
706     {
707         sal_Int32 l = c.length();
708         if( l == 0 )
709             return *this;
710         l += pData->length;
711         rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, l );
712         sal_Unicode* end = c.addData( pData->buffer + pData->length );
713         *end = '\0';
714         pData->length = l;
715         return *this;
716     }
717 
718     /**
719      @overload
720      @internal
721     */
722     template< typename T >
append(OUStringNumber<T> && c)723     OUStringBuffer& append( OUStringNumber< T >&& c )
724     {
725         return append( c.buf, c.length );
726     }
727 #endif
728 
729     /**
730         Appends a 8-Bit ASCII character string to this string buffer.
731 
732        Since this method is optimized for performance. the ASCII
733         character values are not converted in any way. The caller
734         has to make sure that all ASCII characters are in the
735         allowed range between 0 and 127. The ASCII string must be
736         NULL-terminated.
737         <p>
738         The characters of the array argument are appended, in order, to
739         the contents of this string buffer. The length of this string
740         buffer increases by the length of the argument.
741 
742         @param   str   the 8-Bit ASCII characters to be appended.
743         @return  this string buffer.
744      */
appendAscii(const char * str)745     OUStringBuffer & appendAscii( const char * str )
746     {
747         return appendAscii( str, rtl_str_getLength( str ) );
748     }
749 
750     /**
751         Appends a 8-Bit ASCII character string to this string buffer.
752 
753         Since this method is optimized for performance. the ASCII
754         character values are not converted in any way. The caller
755         has to make sure that all ASCII characters are in the
756         allowed range between 0 and 127. The ASCII string must be
757         NULL-terminated.
758         <p>
759         Characters of the character array <code>str</code> are appended,
760         in order, to the contents of this string buffer. The length of this
761         string buffer increases by the value of <code>len</code>.
762 
763         @param str the 8-Bit ASCII characters to be appended; must be non-null,
764         and must point to at least len characters
765         @param len the number of characters to append; must be non-negative
766         @return  this string buffer.
767      */
appendAscii(const char * str,sal_Int32 len)768     OUStringBuffer & appendAscii( const char * str, sal_Int32 len)
769     {
770         rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), str, len );
771         return *this;
772     }
773 
774     /**
775         Appends the string representation of the <code>bool</code>
776         argument to the string buffer.
777 
778         The argument is converted to a string as if by the method
779         <code>String.valueOf</code>, and the characters of that
780         string are then appended to this string buffer.
781 
782         @param   b   a <code>bool</code>.
783         @return  this string buffer.
784 
785         @since LibreOffice 4.1
786      */
append(bool b)787     OUStringBuffer & append(bool b)
788     {
789         sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
790         return append( sz, rtl_ustr_valueOfBoolean( sz, b ) );
791     }
792 
793     /// @cond INTERNAL
794     // Pointer can be automatically converted to bool, which is unwanted here.
795     // Explicitly delete all pointer append() overloads to prevent this
796     // (except for char* and sal_Unicode* overloads, which are handled elsewhere).
797     template< typename T >
798     typename libreoffice_internal::Enable< void,
799         !libreoffice_internal::CharPtrDetector< T* >::ok && !libreoffice_internal::SalUnicodePtrDetector< T* >::ok >::Type
800         append( T* ) SAL_DELETED_FUNCTION;
801     /// @endcond
802 
803     // This overload is needed because OUString has a ctor from rtl_uString*, but
804     // the bool overload above would be preferred to the conversion.
805     /**
806      @internal
807     */
append(rtl_uString * str)808     OUStringBuffer & append(rtl_uString* str)
809     {
810         return append( OUString( str ));
811     }
812 
813     /**
814         Appends the string representation of the <code>sal_Bool</code>
815         argument to the string buffer.
816 
817         The argument is converted to a string as if by the method
818         <code>String.valueOf</code>, and the characters of that
819         string are then appended to this string buffer.
820 
821         @param   b   a <code>sal_Bool</code>.
822         @return  this string buffer.
823      */
append(sal_Bool b)824     OUStringBuffer & append(sal_Bool b)
825     {
826         sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
827         return append( sz, rtl_ustr_valueOfBoolean( sz, b ) );
828     }
829 
830     /**
831         Appends the string representation of the ASCII <code>char</code>
832         argument to this string buffer.
833 
834         The argument is appended to the contents of this string buffer.
835         The length of this string buffer increases by <code>1</code>.
836 
837         @param   c   an ASCII <code>char</code>.
838         @return  this string buffer.
839 
840         @since LibreOffice 3.5
841      */
append(char c)842     OUStringBuffer & append(char c)
843     {
844         assert(static_cast< unsigned char >(c) <= 0x7F);
845         return append(sal_Unicode(c));
846     }
847 
848     /**
849         Appends the string representation of the <code>char</code>
850         argument to this string buffer.
851 
852         The argument is appended to the contents of this string buffer.
853         The length of this string buffer increases by <code>1</code>.
854 
855         @param   c   a <code>char</code>.
856         @return  this string buffer.
857      */
append(sal_Unicode c)858     OUStringBuffer & append(sal_Unicode c)
859     {
860         return append( &c, 1 );
861     }
862 
863 #if defined LIBO_INTERNAL_ONLY
864     void append(sal_uInt16) = delete;
865 #endif
866 
867     /**
868         Appends the string representation of the <code>sal_Int32</code>
869         argument to this string buffer.
870 
871         The argument is converted to a string as if by the method
872         <code>String.valueOf</code>, and the characters of that
873         string are then appended to this string buffer.
874 
875         @param   i   an <code>sal_Int32</code>.
876         @param radix the radix
877         @return  this string buffer.
878      */
append(sal_Int32 i,sal_Int16 radix=10)879     OUStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
880     {
881         sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT32];
882         return append( sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
883     }
884 
885     /**
886         Appends the string representation of the <code>long</code>
887         argument to this string buffer.
888 
889         The argument is converted to a string as if by the method
890         <code>String.valueOf</code>, and the characters of that
891         string are then appended to this string buffer.
892 
893         @param   l   a <code>long</code>.
894         @param radix the radix
895         @return  this string buffer.
896      */
append(sal_Int64 l,sal_Int16 radix=10)897     OUStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
898     {
899         sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT64];
900         return append( sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
901     }
902 
903     /**
904         Appends the string representation of the <code>float</code>
905         argument to this string buffer.
906 
907         The argument is converted to a string as if by the method
908         <code>String.valueOf</code>, and the characters of that
909         string are then appended to this string buffer.
910 
911         @param   f   a <code>float</code>.
912         @return  this string buffer.
913      */
append(float f)914     OUStringBuffer & append(float f)
915     {
916         sal_Unicode sz[RTL_USTR_MAX_VALUEOFFLOAT];
917         return append( sz, rtl_ustr_valueOfFloat( sz, f ) );
918     }
919 
920     /**
921         Appends the string representation of the <code>double</code>
922         argument to this string buffer.
923 
924         The argument is converted to a string as if by the method
925         <code>String.valueOf</code>, and the characters of that
926         string are then appended to this string buffer.
927 
928         @param   d   a <code>double</code>.
929         @return  this string buffer.
930      */
append(double d)931     OUStringBuffer & append(double d)
932     {
933         sal_Unicode sz[RTL_USTR_MAX_VALUEOFDOUBLE];
934         return append( sz, rtl_ustr_valueOfDouble( sz, d ) );
935     }
936 
937     /**
938        Appends a single UTF-32 character to this string buffer.
939 
940        <p>The single UTF-32 character will be represented within the string
941        buffer as either one or two UTF-16 code units.</p>
942 
943        @param c a well-formed UTF-32 code unit (that is, a value in the range
944        <code>0</code>&ndash;<code>0x10FFFF</code>, but excluding
945        <code>0xD800</code>&ndash;<code>0xDFFF</code>)
946 
947        @return
948        this string buffer
949      */
appendUtf32(sal_uInt32 c)950     OUStringBuffer & appendUtf32(sal_uInt32 c) {
951         return insertUtf32(getLength(), c);
952     }
953 
954     /**
955        Unsafe way to make space for a fixed amount of characters to be appended
956        into this OUStringBuffer.
957 
958        A call to this function must immediately be followed by code that
959        completely fills the uninitialized block pointed to by the return value.
960 
961        @param length the length of the uninitialized block of sal_Unicode
962        entities; must be non-negative
963 
964        @return a pointer to the start of the uninitialized block; only valid
965        until this OUStringBuffer's capacity changes
966 
967        @since LibreOffice 4.4
968     */
appendUninitialized(sal_Int32 length)969     sal_Unicode * appendUninitialized(sal_Int32 length) SAL_RETURNS_NONNULL {
970         sal_Int32 n = getLength();
971         rtl_uStringbuffer_insert(&pData, &nCapacity, n, NULL, length);
972         return pData->buffer + n;
973     }
974 
975     /**
976         Inserts the string into this string buffer.
977 
978         The characters of the <code>String</code> argument are inserted, in
979         order, into this string buffer at the indicated offset. The length
980         of this string buffer is increased by the length of the argument.
981         <p>
982         The offset argument must be greater than or equal to
983         <code>0</code>, and less than or equal to the length of this
984         string buffer.
985 
986         @param      offset   the offset.
987         @param      str      a string.
988         @return     this string buffer.
989      */
990 #if defined LIBO_INTERNAL_ONLY
insert(sal_Int32 offset,std::u16string_view str)991     OUStringBuffer & insert(sal_Int32 offset, std::u16string_view str)
992     {
993         return insert( offset, str.data(), str.length() );
994     }
995 #endif
insert(sal_Int32 offset,const OUString & str)996     OUStringBuffer & insert(sal_Int32 offset, const OUString & str)
997     {
998         return insert( offset, str.getStr(), str.getLength() );
999     }
1000 
1001     /**
1002         Inserts the string representation of the <code>char</code> array
1003         argument into this string buffer.
1004 
1005         The characters of the array argument are inserted into the
1006         contents of this string buffer at the position indicated by
1007         <code>offset</code>. The length of this string buffer increases by
1008         the length of the argument.
1009         <p>
1010         The offset argument must be greater than or equal to
1011         <code>0</code>, and less than or equal to the length of this
1012         string buffer.
1013 
1014         @param      offset   the offset.
1015         @param      str      a character array.
1016         @return     this string buffer.
1017      */
insert(sal_Int32 offset,const sal_Unicode * str)1018     OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str )
1019     {
1020         return insert( offset, str, rtl_ustr_getLength( str ) );
1021     }
1022 
1023     /**
1024         Inserts the string representation of the <code>char</code> array
1025         argument into this string buffer.
1026 
1027         The characters of the array argument are inserted into the
1028         contents of this string buffer at the position indicated by
1029         <code>offset</code>. The length of this string buffer increases by
1030         the length of the argument.
1031         <p>
1032         The offset argument must be greater than or equal to
1033         <code>0</code>, and less than or equal to the length of this
1034         string buffer.
1035 
1036         @param      offset   the offset.
1037         @param      str      a character array.
1038         @param      len     the number of characters to append.
1039         @return     this string buffer.
1040      */
insert(sal_Int32 offset,const sal_Unicode * str,sal_Int32 len)1041     OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str, sal_Int32 len)
1042     {
1043         assert( len == 0 || str != NULL ); // cannot assert that in rtl_uStringbuffer_insert
1044         rtl_uStringbuffer_insert( &pData, &nCapacity, offset, str, len );
1045         return *this;
1046     }
1047 
1048     /**
1049         @overload
1050         This function accepts an ASCII string literal as its argument.
1051         @since LibreOffice 3.6
1052      */
1053     template< typename T >
insert(sal_Int32 offset,T & literal)1054     typename libreoffice_internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
1055     {
1056         assert(
1057             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1058         rtl_uStringbuffer_insert_ascii(
1059             &pData, &nCapacity, offset,
1060             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
1061             libreoffice_internal::ConstCharArrayDetector<T>::length);
1062         return *this;
1063     }
1064 
1065 #if defined LIBO_INTERNAL_ONLY
1066     /** @overload @since LibreOffice 5.3 */
1067     template<typename T>
1068     typename libreoffice_internal::ConstCharArrayDetector<
1069         T, OUStringBuffer &>::TypeUtf16
insert(sal_Int32 offset,T & literal)1070     insert(sal_Int32 offset, T & literal) {
1071         return insert(
1072             offset,
1073             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
1074             libreoffice_internal::ConstCharArrayDetector<T>::length);
1075     }
1076 
1077     /** @overload @since LibreOffice 5.4 */
1078     template<std::size_t N>
insert(sal_Int32 offset,OUStringLiteral<N> const & literal)1079     OUStringBuffer & insert(sal_Int32 offset, OUStringLiteral<N> const & literal) {
1080         return insert(offset, literal.getStr(), literal.getLength());
1081     }
1082 #endif
1083 
1084     /**
1085         Inserts the string representation of the <code>sal_Bool</code>
1086         argument into this string buffer.
1087 
1088         The second argument is converted to a string as if by the method
1089         <code>String.valueOf</code>, and the characters of that
1090         string are then inserted into this string buffer at the indicated
1091         offset.
1092         <p>
1093         The offset argument must be greater than or equal to
1094         <code>0</code>, and less than or equal to the length of this
1095         string buffer.
1096 
1097         @param      offset   the offset.
1098         @param      b        a <code>sal_Bool</code>.
1099         @return     this string buffer.
1100      */
insert(sal_Int32 offset,sal_Bool b)1101     OUStringBuffer & insert(sal_Int32 offset, sal_Bool b)
1102     {
1103         sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
1104         return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
1105     }
1106 
1107     /**
1108         Inserts the string representation of the <code>bool</code>
1109         argument into this string buffer.
1110 
1111         The second argument is converted to a string as if by the method
1112         <code>OUString::boolean</code>, and the characters of that
1113         string are then inserted into this string buffer at the indicated
1114         offset.
1115         <p>
1116         The offset argument must be greater than or equal to
1117         <code>0</code>, and less than or equal to the length of this
1118         string buffer.
1119 
1120         @param      offset   the offset.
1121         @param      b        a <code>bool</code>.
1122         @return     this string buffer.
1123 
1124         @since LibreOffice 4.3
1125      */
insert(sal_Int32 offset,bool b)1126     OUStringBuffer & insert(sal_Int32 offset, bool b)
1127     {
1128         sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
1129         return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
1130     }
1131 
1132     /**
1133         Inserts the string representation of the <code>char</code>
1134         argument into this string buffer.
1135 
1136         The second argument is inserted into the contents of this string
1137         buffer at the position indicated by <code>offset</code>. The length
1138         of this string buffer increases by one.
1139         <p>
1140         The offset argument must be greater than or equal to
1141         <code>0</code>, and less than or equal to the length of this
1142         string buffer.
1143 
1144         @param      offset   the offset.
1145         @param      c        a <code>char</code>.
1146         @return     this string buffer.
1147 
1148         @since LibreOffice 3.6
1149      */
insert(sal_Int32 offset,char c)1150     OUStringBuffer & insert(sal_Int32 offset, char c)
1151     {
1152         sal_Unicode u = c;
1153         return insert( offset, &u, 1 );
1154     }
1155 
1156     /**
1157         Inserts the string representation of the <code>char</code>
1158         argument into this string buffer.
1159 
1160         The second argument is inserted into the contents of this string
1161         buffer at the position indicated by <code>offset</code>. The length
1162         of this string buffer increases by one.
1163         <p>
1164         The offset argument must be greater than or equal to
1165         <code>0</code>, and less than or equal to the length of this
1166         string buffer.
1167 
1168         @param      offset   the offset.
1169         @param      c        a <code>char</code>.
1170         @return     this string buffer.
1171      */
insert(sal_Int32 offset,sal_Unicode c)1172     OUStringBuffer & insert(sal_Int32 offset, sal_Unicode c)
1173     {
1174         return insert( offset, &c, 1 );
1175     }
1176 
1177     /**
1178         Inserts the string representation of the second <code>sal_Int32</code>
1179         argument into this string buffer.
1180 
1181         The second argument is converted to a string as if by the method
1182         <code>String.valueOf</code>, and the characters of that
1183         string are then inserted into this string buffer at the indicated
1184         offset.
1185         <p>
1186         The offset argument must be greater than or equal to
1187         <code>0</code>, and less than or equal to the length of this
1188         string buffer.
1189 
1190         @param      offset   the offset.
1191         @param      i        an <code>sal_Int32</code>.
1192         @param      radix    the radix.
1193         @return     this string buffer.
1194         @exception  StringIndexOutOfBoundsException  if the offset is invalid.
1195      */
insert(sal_Int32 offset,sal_Int32 i,sal_Int16 radix=10)1196     OUStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
1197     {
1198         sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT32];
1199         return insert( offset, sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
1200     }
1201 
1202     /**
1203         Inserts the string representation of the <code>long</code>
1204         argument into this string buffer.
1205 
1206         The second argument is converted to a string as if by the method
1207         <code>String.valueOf</code>, and the characters of that
1208         string are then inserted into this string buffer at the indicated
1209         offset.
1210         <p>
1211         The offset argument must be greater than or equal to
1212         <code>0</code>, and less than or equal to the length of this
1213         string buffer.
1214 
1215         @param      offset   the offset.
1216         @param      l        a <code>long</code>.
1217         @param      radix    the radix.
1218         @return     this string buffer.
1219         @exception  StringIndexOutOfBoundsException  if the offset is invalid.
1220      */
insert(sal_Int32 offset,sal_Int64 l,sal_Int16 radix=10)1221     OUStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
1222     {
1223         sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT64];
1224         return insert( offset, sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
1225     }
1226 
1227     /**
1228         Inserts the string representation of the <code>float</code>
1229         argument into this string buffer.
1230 
1231         The second argument is converted to a string as if by the method
1232         <code>String.valueOf</code>, and the characters of that
1233         string are then inserted into this string buffer at the indicated
1234         offset.
1235         <p>
1236         The offset argument must be greater than or equal to
1237         <code>0</code>, and less than or equal to the length of this
1238         string buffer.
1239 
1240         @param      offset   the offset.
1241         @param      f        a <code>float</code>.
1242         @return     this string buffer.
1243         @exception  StringIndexOutOfBoundsException  if the offset is invalid.
1244      */
insert(sal_Int32 offset,float f)1245     OUStringBuffer insert(sal_Int32 offset, float f)
1246     {
1247         sal_Unicode sz[RTL_USTR_MAX_VALUEOFFLOAT];
1248         return insert( offset, sz, rtl_ustr_valueOfFloat( sz, f ) );
1249     }
1250 
1251     /**
1252         Inserts the string representation of the <code>double</code>
1253         argument into this string buffer.
1254 
1255         The second argument is converted to a string as if by the method
1256         <code>String.valueOf</code>, and the characters of that
1257         string are then inserted into this string buffer at the indicated
1258         offset.
1259         <p>
1260         The offset argument must be greater than or equal to
1261         <code>0</code>, and less than or equal to the length of this
1262         string buffer.
1263 
1264         @param      offset   the offset.
1265         @param      d        a <code>double</code>.
1266         @return     this string buffer.
1267         @exception  StringIndexOutOfBoundsException  if the offset is invalid.
1268      */
insert(sal_Int32 offset,double d)1269     OUStringBuffer & insert(sal_Int32 offset, double d)
1270     {
1271         sal_Unicode sz[RTL_USTR_MAX_VALUEOFDOUBLE];
1272         return insert( offset, sz, rtl_ustr_valueOfDouble( sz, d ) );
1273     }
1274 
1275     /**
1276        Inserts a single UTF-32 character into this string buffer.
1277 
1278        <p>The single UTF-32 character will be represented within the string
1279        buffer as either one or two UTF-16 code units.</p>
1280 
1281        @param offset the offset into this string buffer (from zero to the length
1282        of this string buffer, inclusive)
1283 
1284        @param c a well-formed UTF-32 code unit (that is, a value in the range
1285        <code>0</code>&ndash;<code>0x10FFFF</code>, but excluding
1286        <code>0xD800</code>&ndash;<code>0xDFFF</code>)
1287 
1288        @return this string buffer
1289      */
insertUtf32(sal_Int32 offset,sal_uInt32 c)1290     OUStringBuffer & insertUtf32(sal_Int32 offset, sal_uInt32 c) {
1291         rtl_uStringbuffer_insertUtf32(&pData, &nCapacity, offset, c);
1292         return *this;
1293     }
1294 
1295     /**
1296         Removes the characters in a substring of this sequence.
1297 
1298         The substring begins at the specified <code>start</code> and
1299         is <code>len</code> characters long.
1300 
1301         start must be >= 0 && <= This->length
1302 
1303         @param  start       The beginning index, inclusive
1304         @param  len         The substring length
1305         @return this string buffer.
1306      */
remove(sal_Int32 start,sal_Int32 len)1307     OUStringBuffer & remove( sal_Int32 start, sal_Int32 len )
1308     {
1309         rtl_uStringbuffer_remove( &pData, start, len );
1310         return *this;
1311     }
1312 
1313     /**
1314         Removes the tail of a string buffer start at the indicate position
1315 
1316         start must be >= 0 && <= This->length
1317 
1318         @param  start       The beginning index, inclusive. default to 0
1319         @return this string buffer.
1320 
1321         @since LibreOffice 4.0
1322      */
truncate(sal_Int32 start=0)1323     OUStringBuffer & truncate( sal_Int32 start = 0 )
1324     {
1325         rtl_uStringbuffer_remove( &pData, start, getLength() - start );
1326         return *this;
1327     }
1328 
1329     /**
1330        Replace all occurrences of
1331        oldChar in this string buffer with newChar.
1332 
1333        @since LibreOffice 4.0
1334 
1335        @param    oldChar     the old character.
1336        @param    newChar     the new character.
1337        @return   this string buffer
1338     */
replace(sal_Unicode oldChar,sal_Unicode newChar)1339     OUStringBuffer& replace( sal_Unicode oldChar, sal_Unicode newChar )
1340     {
1341         sal_Int32 index = 0;
1342         while((index = indexOf(oldChar, index)) >= 0)
1343         {
1344             pData->buffer[ index ] = newChar;
1345         }
1346         return *this;
1347     }
1348 
1349     /** Allows access to the internal data of this OUStringBuffer, for effective
1350         manipulation.
1351 
1352         This method should be used with care.  After you have called this
1353         method, you may use the returned pInternalData or pInternalCapacity only
1354         as long as you make no other method call on this OUStringBuffer.
1355 
1356         @param pInternalData
1357         This output parameter receives a pointer to the internal data
1358         (rtl_uString pointer).  pInternalData itself must not be null.
1359 
1360         @param pInternalCapacity
1361         This output parameter receives a pointer to the internal capacity.
1362         pInternalCapacity itself must not be null.
1363      */
accessInternals(rtl_uString *** pInternalData,sal_Int32 ** pInternalCapacity)1364     void accessInternals(rtl_uString *** pInternalData,
1365                                 sal_Int32 ** pInternalCapacity)
1366     {
1367         *pInternalData = &pData;
1368         *pInternalCapacity = &nCapacity;
1369     }
1370 
1371 
1372     /**
1373        Returns the index within this string of the first occurrence of the
1374        specified character, starting the search at the specified index.
1375 
1376        @since LibreOffice 4.0
1377 
1378        @param    ch          character to be located.
1379        @param    fromIndex   the index to start the search from.
1380                              The index must be greater or equal than 0
1381                              and less or equal as the string length.
1382        @return   the index of the first occurrence of the character in the
1383                  character sequence represented by this string that is
1384                  greater than or equal to fromIndex, or
1385                  -1 if the character does not occur.
1386     */
indexOf(sal_Unicode ch,sal_Int32 fromIndex=0) const1387     sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const
1388     {
1389         assert( fromIndex >= 0 && fromIndex <= pData->length );
1390         sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
1391         return (ret < 0 ? ret : ret+fromIndex);
1392     }
1393 
1394     /**
1395        Returns the index within this string of the last occurrence of the
1396        specified character, searching backward starting at the end.
1397 
1398        @since LibreOffice 4.0
1399 
1400        @param    ch          character to be located.
1401        @return   the index of the last occurrence of the character in the
1402                  character sequence represented by this string, or
1403                  -1 if the character does not occur.
1404     */
lastIndexOf(sal_Unicode ch) const1405     sal_Int32 lastIndexOf( sal_Unicode ch ) const
1406     {
1407         return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
1408     }
1409 
1410     /**
1411        Returns the index within this string of the last occurrence of the
1412        specified character, searching backward starting before the specified
1413        index.
1414 
1415        @since LibreOffice 4.0
1416 
1417        @param    ch          character to be located.
1418        @param    fromIndex   the index before which to start the search.
1419        @return   the index of the last occurrence of the character in the
1420                  character sequence represented by this string that
1421                  is less than fromIndex, or -1
1422                  if the character does not occur before that point.
1423     */
lastIndexOf(sal_Unicode ch,sal_Int32 fromIndex) const1424     sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const
1425     {
1426         assert( fromIndex >= 0 && fromIndex <= pData->length );
1427         return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
1428     }
1429 
1430     /**
1431        Returns the index within this string of the first occurrence of the
1432        specified substring, starting at the specified index.
1433 
1434        If str doesn't include any character, always -1 is
1435        returned. This is also the case, if both strings are empty.
1436 
1437        @since LibreOffice 4.0
1438 
1439        @param    str         the substring to search for.
1440        @param    fromIndex   the index to start the search from.
1441        @return   If the string argument occurs one or more times as a substring
1442                  within this string at the starting index, then the index
1443                  of the first character of the first such substring is
1444                  returned. If it does not occur as a substring starting
1445                  at fromIndex or beyond, -1 is returned.
1446     */
1447 #if defined LIBO_INTERNAL_ONLY
indexOf(std::u16string_view str,sal_Int32 fromIndex=0) const1448     sal_Int32 indexOf( std::u16string_view str, sal_Int32 fromIndex = 0 ) const
1449     {
1450         assert( fromIndex >= 0 && fromIndex <= pData->length );
1451         sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1452                                                         str.data(), str.length() );
1453         return (ret < 0 ? ret : ret+fromIndex);
1454     }
1455 #endif
indexOf(const OUString & str,sal_Int32 fromIndex=0) const1456     sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const
1457     {
1458         assert( fromIndex >= 0 && fromIndex <= pData->length );
1459         sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1460                                                         str.pData->buffer, str.pData->length );
1461         return (ret < 0 ? ret : ret+fromIndex);
1462     }
1463 
1464     /**
1465        @overload
1466        This function accepts an ASCII string literal as its argument.
1467 
1468        @since LibreOffice 4.0
1469     */
1470     template< typename T >
indexOf(T & literal,sal_Int32 fromIndex=0) const1471     typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const
1472     {
1473         assert(
1474             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1475         sal_Int32 n = rtl_ustr_indexOfAscii_WithLength(
1476             pData->buffer + fromIndex, pData->length - fromIndex,
1477             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
1478             libreoffice_internal::ConstCharArrayDetector<T>::length);
1479         return n < 0 ? n : n + fromIndex;
1480     }
1481 
1482 #if defined LIBO_INTERNAL_ONLY
1483     /** @overload @since LibreOffice 5.3 */
1484     template<typename T>
1485     typename
1486         libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16
indexOf(T & literal,sal_Int32 fromIndex=0) const1487     indexOf(T & literal, sal_Int32 fromIndex = 0) const {
1488         assert(fromIndex >= 0);
1489         auto n = rtl_ustr_indexOfStr_WithLength(
1490             pData->buffer + fromIndex, pData->length - fromIndex,
1491             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
1492             libreoffice_internal::ConstCharArrayDetector<T>::length);
1493         return n < 0 ? n : n + fromIndex;
1494     }
1495 
1496     /** @overload @since LibreOffice 5.4 */
1497     template<std::size_t N>
indexOf(OUStringLiteral<N> const & literal,sal_Int32 fromIndex=0) const1498     sal_Int32 indexOf(OUStringLiteral<N> const & literal, sal_Int32 fromIndex = 0)
1499         const
1500     {
1501         sal_Int32 n = rtl_ustr_indexOfStr_WithLength(
1502             pData->buffer + fromIndex, pData->length - fromIndex, literal.getStr(),
1503             literal.getLength());
1504         return n < 0 ? n : n + fromIndex;
1505     }
1506 #endif
1507 
1508     /**
1509        Returns the index within this string of the last occurrence of
1510        the specified substring, searching backward starting at the end.
1511 
1512        The returned index indicates the starting index of the substring
1513        in this string.
1514        If str doesn't include any character, always -1 is
1515        returned. This is also the case, if both strings are empty.
1516 
1517        @since LibreOffice 4.0
1518 
1519        @param    str         the substring to search for.
1520        @return   If the string argument occurs one or more times as a substring
1521                  within this string, then the index of the first character of
1522                  the last such substring is returned. If it does not occur as
1523                  a substring, -1 is returned.
1524     */
1525 #if defined LIBO_INTERNAL_ONLY
lastIndexOf(std::u16string_view str) const1526     sal_Int32 lastIndexOf( std::u16string_view str ) const
1527     {
1528         return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1529                                                    str.data(), str.length() );
1530     }
1531 #endif
lastIndexOf(const OUString & str) const1532     sal_Int32 lastIndexOf( const OUString & str ) const
1533     {
1534         return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1535                                                    str.pData->buffer, str.pData->length );
1536     }
1537 
1538     /**
1539        Returns the index within this string of the last occurrence of
1540        the specified substring, searching backward starting before the specified
1541        index.
1542 
1543        The returned index indicates the starting index of the substring
1544        in this string.
1545        If str doesn't include any character, always -1 is
1546        returned. This is also the case, if both strings are empty.
1547 
1548        @since LibreOffice 4.0
1549 
1550        @param    str         the substring to search for.
1551        @param    fromIndex   the index before which to start the search.
1552        @return   If the string argument occurs one or more times as a substring
1553                  within this string before the starting index, then the index
1554                  of the first character of the last such substring is
1555                  returned. Otherwise, -1 is returned.
1556     */
lastIndexOf(const OUString & str,sal_Int32 fromIndex) const1557     sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const
1558     {
1559         assert( fromIndex >= 0 && fromIndex <= pData->length );
1560         return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1561                                                    str.pData->buffer, str.pData->length );
1562     }
1563 
1564     /**
1565        @overload
1566        This function accepts an ASCII string literal as its argument.
1567        @since LibreOffice 4.0
1568     */
1569     template< typename T >
lastIndexOf(T & literal) const1570     typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const
1571     {
1572         assert(
1573             libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
1574         return rtl_ustr_lastIndexOfAscii_WithLength(
1575             pData->buffer, pData->length,
1576             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
1577             libreoffice_internal::ConstCharArrayDetector<T>::length);
1578     }
1579 
1580 #if defined LIBO_INTERNAL_ONLY
1581     /** @overload @since LibreOffice 5.3 */
1582     template<typename T>
1583     typename
1584         libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16
lastIndexOf(T & literal) const1585     lastIndexOf(T & literal) const {
1586         return rtl_ustr_lastIndexOfStr_WithLength(
1587             pData->buffer, pData->length,
1588             libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
1589             libreoffice_internal::ConstCharArrayDetector<T>::length);
1590     }
1591 
1592     /** @overload @since LibreOffice 5.4 */
lastIndexOf(OUStringLiteral<N> const & literal) const1593     template<std::size_t N> sal_Int32 lastIndexOf(OUStringLiteral<N> const & literal) const {
1594         return rtl_ustr_lastIndexOfStr_WithLength(
1595             pData->buffer, pData->length, literal.getStr(), literal.getLength());
1596     }
1597 #endif
1598 
1599     /**
1600        Strip the given character from the start of the buffer.
1601 
1602        @since LibreOffice 4.0
1603 
1604        @param    c         the character to strip
1605        @return   The number of characters stripped
1606 
1607     */
stripStart(sal_Unicode c=' ')1608     sal_Int32 stripStart(sal_Unicode c = ' ')
1609     {
1610         sal_Int32 index;
1611         for(index = 0; index < getLength() ; index++)
1612         {
1613             if(pData->buffer[ index ] != c)
1614             {
1615                 break;
1616             }
1617         }
1618         if(index)
1619         {
1620             remove(0, index);
1621         }
1622         return index;
1623     }
1624 
1625     /**
1626        Strip the given character from the end of the buffer.
1627 
1628        @since LibreOffice 4.0
1629 
1630        @param    c         the character to strip
1631        @return   The number of characters stripped
1632 
1633     */
stripEnd(sal_Unicode c=' ')1634     sal_Int32 stripEnd(sal_Unicode c = ' ')
1635     {
1636         sal_Int32 result = getLength();
1637         sal_Int32 index;
1638         for(index = getLength(); index > 0 ; index--)
1639         {
1640             if(pData->buffer[ index - 1 ] != c)
1641             {
1642                 break;
1643             }
1644         }
1645         if(index < getLength())
1646         {
1647             truncate(index);
1648         }
1649         return result - getLength();
1650     }
1651     /**
1652        Strip the given character from the both end of the buffer.
1653 
1654        @since LibreOffice 4.0
1655 
1656        @param    c         the character to strip
1657        @return   The number of characters stripped
1658 
1659     */
strip(sal_Unicode c=' ')1660     sal_Int32 strip(sal_Unicode c = ' ')
1661     {
1662         return stripStart(c) + stripEnd(c);
1663     }
1664 
1665 #if defined LIBO_INTERNAL_ONLY
1666     /**
1667       Returns a std::u16string_view that is a view of a substring of this string.
1668 
1669       The substring begins at the specified beginIndex. If
1670       beginIndex is negative or be greater than the length of
1671       this string, behaviour is undefined.
1672 
1673       @param     beginIndex   the beginning index, inclusive.
1674       @return    the specified substring.
1675     */
subView(sal_Int32 beginIndex) const1676     SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex ) const
1677     {
1678         assert(beginIndex >= 0);
1679         assert(beginIndex <= getLength());
1680         return subView(beginIndex, getLength() - beginIndex);
1681     }
1682 
1683     /**
1684       Returns a std::u16string_view that is a view of a substring of this string.
1685 
1686       The substring begins at the specified beginIndex and contains count
1687       characters.  If either beginIndex or count are negative,
1688       or beginIndex + count are greater than the length of this string
1689       then behaviour is undefined.
1690 
1691       @param     beginIndex   the beginning index, inclusive.
1692       @param     count        the number of characters.
1693       @return    the specified substring.
1694     */
subView(sal_Int32 beginIndex,sal_Int32 count) const1695     SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex, sal_Int32 count ) const
1696     {
1697         assert(beginIndex >= 0);
1698         assert(count >= 0);
1699         assert(beginIndex <= getLength());
1700         assert(count <= getLength() - beginIndex);
1701         return std::u16string_view(pData->buffer, sal_uInt32(pData->length)).substr(beginIndex, count);
1702     }
1703 #endif
1704 
1705     /**
1706       Returns a new string buffer that is a substring of this string.
1707 
1708       The substring begins at the specified beginIndex. If
1709       beginIndex is negative or be greater than the length of
1710       this string, behaviour is undefined.
1711 
1712       @param     beginIndex   the beginning index, inclusive.
1713       @return    the specified substring.
1714       @since LibreOffice 4.1
1715     */
copy(sal_Int32 beginIndex) const1716     OUStringBuffer copy( sal_Int32 beginIndex ) const
1717     {
1718         return copy( beginIndex, getLength() - beginIndex );
1719     }
1720 
1721     /**
1722       Returns a new string buffer that is a substring of this string.
1723 
1724       The substring begins at the specified beginIndex and contains count
1725       characters.  If either beginIndex or count are negative,
1726       or beginIndex + count are greater than the length of this string
1727       then behaviour is undefined.
1728 
1729       @param     beginIndex   the beginning index, inclusive.
1730       @param     count        the number of characters.
1731       @return    the specified substring.
1732       @since LibreOffice 4.1
1733     */
copy(sal_Int32 beginIndex,sal_Int32 count) const1734     OUStringBuffer copy( sal_Int32 beginIndex, sal_Int32 count ) const
1735     {
1736         assert(beginIndex >= 0 && beginIndex <= getLength());
1737         assert(count >= 0 && count <= getLength() - beginIndex);
1738         rtl_uString *pNew = NULL;
1739         rtl_uStringbuffer_newFromStr_WithLength( &pNew, getStr() + beginIndex, count );
1740         return OUStringBuffer( pNew, count + 16 );
1741     }
1742 
1743 private:
OUStringBuffer(rtl_uString * value,const sal_Int32 capacity)1744     OUStringBuffer( rtl_uString * value, const sal_Int32 capacity )
1745     {
1746         pData = value;
1747         nCapacity = capacity;
1748     }
1749 
1750     /**
1751         A pointer to the data structure which contains the data.
1752      */
1753     rtl_uString * pData;
1754 
1755     /**
1756         The len of the pData->buffer.
1757      */
1758     sal_Int32       nCapacity;
1759 };
1760 
1761 #if defined LIBO_INTERNAL_ONLY
1762 template<> struct ToStringHelper<OUStringBuffer> {
lengthrtl::ToStringHelper1763     static std::size_t length(OUStringBuffer const & s) { return s.getLength(); }
1764 
addDatartl::ToStringHelper1765     static sal_Unicode * addData(sal_Unicode * buffer, OUStringBuffer const & s) SAL_RETURNS_NONNULL
1766     { return addDataHelper(buffer, s.getStr(), s.getLength()); }
1767 
1768     static constexpr bool allowOStringConcat = false;
1769     static constexpr bool allowOUStringConcat = true;
1770 };
1771 #endif
1772 
1773 #if defined LIBO_INTERNAL_ONLY
1774     // Define this here to avoid circular includes
operator +=(const OUStringBuffer & str)1775     inline OUString & OUString::operator+=( const OUStringBuffer & str ) &
1776     {
1777         // Call operator= if this is empty, otherwise rtl_uString_newConcat will attempt to
1778         // acquire() the str.pData buffer, which is part of the OUStringBuffer mutable state.
1779         if (isEmpty())
1780             return operator=(str.toString());
1781         else
1782             return internalAppend(str.pData);
1783     }
1784 #endif
1785 }
1786 
1787 #ifdef RTL_STRING_UNITTEST
1788 namespace rtl
1789 {
1790 typedef rtlunittest::OUStringBuffer OUStringBuffer;
1791 }
1792 #endif
1793 
1794 #if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
1795 using ::rtl::OUStringBuffer;
1796 #endif
1797 
1798 #endif // INCLUDED_RTL_USTRBUF_HXX
1799 
1800 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1801