LibreOffice
LibreOffice 7.4 SDK C/C++ API Reference
ustrbuf.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 /*
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 #include <type_traits>
37 #endif
38 
39 #include "rtl/ustrbuf.h"
40 #include "rtl/ustring.hxx"
41 #include "rtl/stringutils.hxx"
42 #include "sal/types.h"
43 
44 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
45 #include "rtl/stringconcat.hxx"
46 #endif
47 
48 #ifdef RTL_STRING_UNITTEST
49 extern bool rtl_string_unittest_invalid_conversion;
50 #endif
51 
52 // The unittest uses slightly different code to help check that the proper
53 // calls are made. The class is put into a different namespace to make
54 // sure the compiler generates a different (if generating also non-inline)
55 // copy of the function and does not merge them together. The class
56 // is "brought" into the proper rtl namespace by a typedef below.
57 #ifdef RTL_STRING_UNITTEST
58 #define rtl rtlunittest
59 #endif
60 
61 namespace rtl
62 {
63 
64 #ifdef RTL_STRING_UNITTEST
65 #undef rtl
66 #endif
67 
71 {
72 friend class OUString;
73 public:
79  : pData(NULL)
80  , nCapacity( 16 )
81  {
82  rtl_uString_new_WithLength( &pData, nCapacity );
83  }
84 
91  OUStringBuffer( const OUStringBuffer & value )
92  : pData(NULL)
93  , nCapacity( value.nCapacity )
94  {
95  rtl_uStringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
96  }
97 
104  explicit OUStringBuffer(sal_Int32 length)
105  : pData(NULL)
106  , nCapacity( length )
107  {
108  rtl_uString_new_WithLength( &pData, length );
109  }
110 #if defined LIBO_INTERNAL_ONLY
111  template<typename T>
112  explicit OUStringBuffer(T length, std::enable_if_t<std::is_integral_v<T>, int> = 0)
113  : OUStringBuffer(static_cast<sal_Int32>(length))
114  {
115  assert(
116  length >= 0
117  && static_cast<std::make_unsigned_t<T>>(length)
118  <= static_cast<std::make_unsigned_t<sal_Int32>>(
119  std::numeric_limits<sal_Int32>::max()));
120  }
121  // avoid (obvious) bugs
122  explicit OUStringBuffer(bool) = delete;
123  explicit OUStringBuffer(char) = delete;
124  explicit OUStringBuffer(wchar_t) = delete;
125 #if defined __cpp_char8_t
126  explicit OUStringBuffer(char8_t) = delete;
127 #endif
128  explicit OUStringBuffer(char16_t) = delete;
129  explicit OUStringBuffer(char32_t) = delete;
130 #endif
131 
142 #if defined LIBO_INTERNAL_ONLY
143  OUStringBuffer(std::u16string_view sv)
144  : pData(nullptr)
145  , nCapacity( sv.length() + 16 )
146  {
147  if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
148  throw std::bad_alloc();
149  }
150  rtl_uStringbuffer_newFromStr_WithLength( &pData, sv.data(), sv.length() );
151  }
152 #else
153  OUStringBuffer(const OUString& value)
154  : pData(NULL)
155  , nCapacity( value.getLength() + 16 )
156  {
157  rtl_uStringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
158  }
159 #endif
160 
161  template< typename T >
163  : pData(NULL)
164  , nCapacity( libreoffice_internal::ConstCharArrayDetector<T>::length + 16 )
165  {
166  assert(
169  &pData,
172 #ifdef RTL_STRING_UNITTEST
173  rtl_string_unittest_const_literal = true;
174 #endif
175  }
176 
177 #if defined LIBO_INTERNAL_ONLY
179  template<typename T>
181  T & literal,
183  T, libreoffice_internal::Dummy>::TypeUtf16
185  pData(nullptr),
186  nCapacity(libreoffice_internal::ConstCharArrayDetector<T>::length + 16)
187  {
189  &pData,
192  }
193 #endif
194 
195 #if defined LIBO_INTERNAL_ONLY && defined RTL_STRING_UNITTEST
197 
201  template< typename T >
202  OUStringBuffer( T&, typename libreoffice_internal::ExceptConstCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
203  {
204  pData = NULL;
205  nCapacity = 10;
206  rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
207  rtl_string_unittest_invalid_conversion = true;
208  }
213  template< typename T >
214  OUStringBuffer( const T&, typename libreoffice_internal::ExceptCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
215  {
216  pData = NULL;
217  nCapacity = 10;
218  rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
219  rtl_string_unittest_invalid_conversion = true;
220  }
222 #endif
223 
224 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
229  template< typename T1, typename T2 >
230  OUStringBuffer( OUStringConcat< T1, T2 >&& c )
231  {
232  const sal_Int32 l = c.length();
233  nCapacity = l + 16;
234  pData = rtl_uString_alloc( nCapacity );
235  sal_Unicode* end = c.addData( pData->buffer );
236  *end = '\0';
237  pData->length = l;
238  }
239 
244  template< typename T >
245  OUStringBuffer( OUStringNumber< T >&& n )
246  : pData(NULL)
247  , nCapacity( n.length + 16 )
248  {
249  rtl_uStringbuffer_newFromStr_WithLength( &pData, n.buf, n.length );
250  }
251 #endif
252 
253 #if defined LIBO_INTERNAL_ONLY
254  operator std::u16string_view() const { return {getStr(), sal_uInt32(getLength())}; }
255 #endif
256 
259  OUStringBuffer& operator = ( const OUStringBuffer& value )
260  {
261  if (this != &value)
262  {
264  value.nCapacity,
265  value.pData);
266  nCapacity = value.nCapacity;
267  }
268  return *this;
269  }
270 
271 #if defined LIBO_INTERNAL_ONLY
275  OUStringBuffer& operator = ( OUStringBuffer&& value ) noexcept
276  {
277  rtl_uString_release( pData );
278  pData = value.pData;
279  nCapacity = value.nCapacity;
280  value.pData = nullptr;
281  value.nCapacity = 0;
282  rtl_uString_new( &value.pData );
283  return *this;
284  }
285 #endif
286 
291 #if defined LIBO_INTERNAL_ONLY
292  OUStringBuffer & operator =(std::u16string_view string) {
293  sal_Int32 n = string.length();
294  if (n >= nCapacity) {
295  ensureCapacity(n + 16); //TODO: check for overflow
296  }
297  std::memcpy(
298  pData->buffer, string.data(),
299  n * sizeof (sal_Unicode));
300  pData->buffer[n] = '\0';
301  pData->length = n;
302  return *this;
303  }
304 #else
305  OUStringBuffer & operator =(OUString const & string) {
306  sal_Int32 n = string.getLength();
307  if (n >= nCapacity) {
308  ensureCapacity(n + 16); //TODO: check for overflow
309  }
310  std::memcpy(
311  pData->buffer, string.pData->buffer,
312  (n + 1) * sizeof (sal_Unicode));
313  pData->length = n;
314  return *this;
315  }
316 #endif
317 
322  template<typename T>
323  typename
325  operator =(T & literal) {
326  assert(
328  sal_Int32 const n
330  if (n >= nCapacity) {
331  ensureCapacity(n + 16); //TODO: check for overflow
332  }
333  char const * from
335  literal);
336  sal_Unicode * to = pData->buffer;
337  for (sal_Int32 i = 0; i <= n; ++i) {
338  to[i] = from[i];
339  }
340  pData->length = n;
341  return *this;
342  }
343 
344 #if defined LIBO_INTERNAL_ONLY
346  template<typename T>
348  T, OUStringBuffer &>::TypeUtf16
349  operator =(T & literal) {
350  sal_Int32 const n
352  if (n >= nCapacity) {
353  ensureCapacity(n + 16); //TODO: check for overflow
354  }
355  // For OUStringChar, which is covered by this template's ConstCharArrayDetector TypeUtf16
356  // check, toPointer does not return a NUL-terminated string, so we can't just memcpy n+1
357  // elements but rather need to add the terminating NUL manually:
358  std::memcpy(
359  pData->buffer,
360  libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
361  n * sizeof (sal_Unicode));
362  pData->buffer[n] = '\0';
363  pData->length = n;
364  return *this;
365  }
366 #endif
367 
368 #if defined LIBO_INTERNAL_ONLY
370  template<typename T1, typename T2>
371  OUStringBuffer & operator =(OUStringConcat<T1, T2> && concat) {
372  sal_Int32 const n = concat.length();
373  if (n >= nCapacity) {
374  ensureCapacity(n + 16); //TODO: check for overflow
375  }
376  *concat.addData(pData->buffer) = 0;
377  pData->length = n;
378  return *this;
379  }
380 
382  template<typename T>
383  OUStringBuffer & operator =(OUStringNumber<T> && n)
384  {
385  *this = OUStringBuffer( std::move( n ) );
386  return *this;
387  }
388 #endif
389 
394  {
395  rtl_uString_release( pData );
396  }
397 
407  {
408  return OUString(
409  rtl_uStringBuffer_makeStringAndClear( &pData, &nCapacity ),
410  SAL_NO_ACQUIRE );
411  }
412 
418  sal_Int32 getLength() const
419  {
420  return pData->length;
421  }
422 
431  bool isEmpty() const
432  {
433  return pData->length == 0;
434  }
435 
446  sal_Int32 getCapacity() const
447  {
448  return nCapacity;
449  }
450 
462  void ensureCapacity(sal_Int32 minimumCapacity)
463  {
464  rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
465  }
466 
485  void setLength(sal_Int32 newLength)
486  {
487  assert(newLength >= 0);
488  // Avoid modifications if pData points to const empty string:
489  if( newLength != pData->length )
490  {
491  if( newLength > nCapacity )
492  rtl_uStringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
493  else
494  pData->buffer[newLength] = 0;
495  pData->length = newLength;
496  }
497  }
498 
512  SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
513  sal_Unicode charAt( sal_Int32 index ) const
514  {
515  assert(index >= 0 && index < pData->length);
516  return pData->buffer[ index ];
517  }
518 
529  SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
530  OUStringBuffer & setCharAt(sal_Int32 index, sal_Unicode ch)
531  {
532  assert(index >= 0 && index < pData->length);
533  pData->buffer[ index ] = ch;
534  return *this;
535  }
536 
540  const sal_Unicode* getStr() const SAL_RETURNS_NONNULL { return pData->buffer; }
541 
551  sal_Unicode & operator [](sal_Int32 index)
552  {
553  assert(index >= 0 && index < pData->length);
554  return pData->buffer[index];
555  }
556 
566  const sal_Unicode & operator [](sal_Int32 index) const
567  {
568  assert(index >= 0 && index < pData->length);
569  return pData->buffer[index];
570  }
571 
577  {
578  return OUString(pData->buffer, pData->length);
579  }
580 
591 #if !defined LIBO_INTERNAL_ONLY
593  {
594  return append( str.getStr(), str.getLength() );
595  }
596 #else
597  OUStringBuffer & append(std::u16string_view sv) {
598  if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
599  throw std::bad_alloc();
600  }
601  return append(sv.data(), sv.size());
602  }
603 #endif
604 
605 #if !defined LIBO_INTERNAL_ONLY
619  {
620  if(!str.isEmpty())
621  {
622  append( str.getStr(), str.getLength() );
623  }
624  return *this;
625  }
626 #endif
627 
639 #if defined LIBO_INTERNAL_ONLY
640  template<typename T>
642  append(T const & str)
643 #else
645 #endif
646  {
647  return append( str, rtl_ustr_getLength( str ) );
648  }
649 
663  OUStringBuffer & append( const sal_Unicode * str, sal_Int32 len)
664  {
665  assert( len == 0 || str != NULL ); // cannot assert that in rtl_uStringbuffer_insert
666  rtl_uStringbuffer_insert( &pData, &nCapacity, getLength(), str, len );
667  return *this;
668  }
669 
675  template< typename T >
677  {
678  assert(
680  return appendAscii(
683  }
684 
685 #if defined LIBO_INTERNAL_ONLY
686  template<typename T>
688  append(T & value) { return append(static_cast<sal_Unicode *>(value)); }
689 
691  template<typename T>
692  typename libreoffice_internal::ConstCharArrayDetector<
693  T, OUStringBuffer &>::TypeUtf16
694  append(T & literal) {
695  return append(
696  libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
697  libreoffice_internal::ConstCharArrayDetector<T>::length);
698  }
699 #endif
700 
701 #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
706  template< typename T1, typename T2 >
707  OUStringBuffer& append( OUStringConcat< T1, T2 >&& c )
708  {
709  sal_Int32 l = c.length();
710  if( l == 0 )
711  return *this;
712  l += pData->length;
713  rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, l );
714  sal_Unicode* end = c.addData( pData->buffer + pData->length );
715  *end = '\0';
716  pData->length = l;
717  return *this;
718  }
719 
724  template< typename T >
725  OUStringBuffer& append( OUStringNumber< T >&& c )
726  {
727  return append( c.buf, c.length );
728  }
729 #endif
730 
747  OUStringBuffer & appendAscii( const char * str )
748  {
749  return appendAscii( str, rtl_str_getLength( str ) );
750  }
751 
770  OUStringBuffer & appendAscii( const char * str, sal_Int32 len)
771  {
772  rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), str, len );
773  return *this;
774  }
775 
790  {
792  return append( sz, rtl_ustr_valueOfBoolean( sz, b ) );
793  }
794 
796  // Pointer can be automatically converted to bool, which is unwanted here.
797  // Explicitly delete all pointer append() overloads to prevent this
798  // (except for char* and sal_Unicode* overloads, which are handled elsewhere).
799  template< typename T >
800  typename libreoffice_internal::Enable< void,
802  append( T* ) SAL_DELETED_FUNCTION;
804 
805  // This overload is needed because OUString has a ctor from rtl_uString*, but
806  // the bool overload above would be preferred to the conversion.
810  OUStringBuffer & append(rtl_uString* str)
811  {
812  return append( OUString( str ));
813  }
814 
827  {
829  return append( sz, rtl_ustr_valueOfBoolean( sz, b ) );
830  }
831 
845  {
846  assert(static_cast< unsigned char >(c) <= 0x7F);
847  return append(sal_Unicode(c));
848  }
849 
861  {
862  return append( &c, 1 );
863  }
864 
865 #if defined LIBO_INTERNAL_ONLY
866  void append(sal_uInt16) = delete;
867 #endif
868 
881  OUStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
882  {
884  return append( sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
885  }
886 
899  OUStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
900  {
902  return append( sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
903  }
904 
917  {
919  return append( sz, rtl_ustr_valueOfFloat( sz, f ) );
920  }
921 
933  OUStringBuffer & append(double d)
934  {
936  return append( sz, rtl_ustr_valueOfDouble( sz, d ) );
937  }
938 
952  OUStringBuffer & appendUtf32(sal_uInt32 c) {
953  return insertUtf32(getLength(), c);
954  }
955 
971  sal_Unicode * appendUninitialized(sal_Int32 length) SAL_RETURNS_NONNULL {
972  sal_Int32 n = getLength();
973  rtl_uStringbuffer_insert(&pData, &nCapacity, n, NULL, length);
974  return pData->buffer + n;
975  }
976 
992 #if defined LIBO_INTERNAL_ONLY
993  OUStringBuffer & insert(sal_Int32 offset, std::u16string_view str)
994  {
995  return insert( offset, str.data(), str.length() );
996  }
997 #else
998  OUStringBuffer & insert(sal_Int32 offset, const OUString & str)
999  {
1000  return insert( offset, str.getStr(), str.getLength() );
1001  }
1002 #endif
1003 
1021  OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str )
1022  {
1023  return insert( offset, str, rtl_ustr_getLength( str ) );
1024  }
1025 
1044  OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str, sal_Int32 len)
1045  {
1046  assert( len == 0 || str != NULL ); // cannot assert that in rtl_uStringbuffer_insert
1047  rtl_uStringbuffer_insert( &pData, &nCapacity, offset, str, len );
1048  return *this;
1049  }
1050 
1056  template< typename T >
1058  {
1059  assert(
1062  &pData, &nCapacity, offset,
1065  return *this;
1066  }
1067 
1068 #if defined LIBO_INTERNAL_ONLY
1070  template<typename T>
1072  T, OUStringBuffer &>::TypeUtf16
1073  insert(sal_Int32 offset, T & literal) {
1074  return insert(
1075  offset,
1078  }
1079 #endif
1080 
1098  OUStringBuffer & insert(sal_Int32 offset, sal_Bool b)
1099  {
1101  return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
1102  }
1103 
1123  OUStringBuffer & insert(sal_Int32 offset, bool b)
1124  {
1126  return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
1127  }
1128 
1147  OUStringBuffer & insert(sal_Int32 offset, char c)
1148  {
1149  sal_Unicode u = c;
1150  return insert( offset, &u, 1 );
1151  }
1152 
1169  OUStringBuffer & insert(sal_Int32 offset, sal_Unicode c)
1170  {
1171  return insert( offset, &c, 1 );
1172  }
1173 
1193  OUStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
1194  {
1196  return insert( offset, sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
1197  }
1198 
1218  OUStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
1219  {
1221  return insert( offset, sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
1222  }
1223 
1242  OUStringBuffer insert(sal_Int32 offset, float f)
1243  {
1245  return insert( offset, sz, rtl_ustr_valueOfFloat( sz, f ) );
1246  }
1247 
1266  OUStringBuffer & insert(sal_Int32 offset, double d)
1267  {
1269  return insert( offset, sz, rtl_ustr_valueOfDouble( sz, d ) );
1270  }
1271 
1287  OUStringBuffer & insertUtf32(sal_Int32 offset, sal_uInt32 c) {
1288  rtl_uStringbuffer_insertUtf32(&pData, &nCapacity, offset, c);
1289  return *this;
1290  }
1291 
1304  OUStringBuffer & remove( sal_Int32 start, sal_Int32 len )
1305  {
1306  rtl_uStringbuffer_remove( &pData, start, len );
1307  return *this;
1308  }
1309 
1320  OUStringBuffer & truncate( sal_Int32 start = 0 )
1321  {
1322  rtl_uStringbuffer_remove( &pData, start, getLength() - start );
1323  return *this;
1324  }
1325 
1337  {
1338  sal_Int32 index = 0;
1339  while((index = indexOf(oldChar, index)) >= 0)
1340  {
1341  pData->buffer[ index ] = newChar;
1342  }
1343  return *this;
1344  }
1345 
1361  void accessInternals(rtl_uString *** pInternalData,
1362  sal_Int32 ** pInternalCapacity)
1363  {
1364  *pInternalData = &pData;
1365  *pInternalCapacity = &nCapacity;
1366  }
1367 
1368 
1384  sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const
1385  {
1386  assert( fromIndex >= 0 && fromIndex <= pData->length );
1387  sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
1388  return (ret < 0 ? ret : ret+fromIndex);
1389  }
1390 
1402  sal_Int32 lastIndexOf( sal_Unicode ch ) const
1403  {
1404  return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
1405  }
1406 
1421  sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const
1422  {
1423  assert( fromIndex >= 0 && fromIndex <= pData->length );
1424  return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
1425  }
1426 
1444 #if defined LIBO_INTERNAL_ONLY
1445  sal_Int32 indexOf( std::u16string_view str, sal_Int32 fromIndex = 0 ) const
1446  {
1447  assert( fromIndex >= 0 && fromIndex <= pData->length );
1448  sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1449  str.data(), str.length() );
1450  return (ret < 0 ? ret : ret+fromIndex);
1451  }
1452 #else
1453  sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const
1454  {
1455  assert( fromIndex >= 0 && fromIndex <= pData->length );
1456  sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1457  str.pData->buffer, str.pData->length );
1458  return (ret < 0 ? ret : ret+fromIndex);
1459  }
1460 #endif
1461 
1468  template< typename T >
1469  typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const
1470  {
1471  assert(
1473  sal_Int32 n = rtl_ustr_indexOfAscii_WithLength(
1474  pData->buffer + fromIndex, pData->length - fromIndex,
1477  return n < 0 ? n : n + fromIndex;
1478  }
1479 
1480 #if defined LIBO_INTERNAL_ONLY
1482  template<typename T>
1483  typename
1485  indexOf(T & literal, sal_Int32 fromIndex = 0) const {
1486  assert(fromIndex >= 0);
1488  pData->buffer + fromIndex, pData->length - fromIndex,
1491  return n < 0 ? n : n + fromIndex;
1492  }
1493 #endif
1494 
1512 #if defined LIBO_INTERNAL_ONLY
1513  sal_Int32 lastIndexOf( std::u16string_view str ) const
1514  {
1515  return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1516  str.data(), str.length() );
1517  }
1518 #else
1519  sal_Int32 lastIndexOf( const OUString & str ) const
1520  {
1521  return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1522  str.pData->buffer, str.pData->length );
1523  }
1524 #endif
1525 
1545 #if defined LIBO_INTERNAL_ONLY
1546  sal_Int32 lastIndexOf( std::u16string_view str, sal_Int32 fromIndex ) const
1547  {
1548  assert( fromIndex >= 0 && fromIndex <= pData->length );
1549  return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1550  str.data(), str.length() );
1551  }
1552 #else
1553  sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const
1554  {
1555  assert( fromIndex >= 0 && fromIndex <= pData->length );
1556  return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1557  str.pData->buffer, str.pData->length );
1558  }
1559 #endif
1560 
1566  template< typename T >
1568  {
1569  assert(
1572  pData->buffer, pData->length,
1575  }
1576 
1577 #if defined LIBO_INTERNAL_ONLY
1579  template<typename T>
1580  typename
1582  lastIndexOf(T & literal) const {
1584  pData->buffer, pData->length,
1587  }
1588 #endif
1589 
1599  sal_Int32 stripStart(sal_Unicode c = ' ')
1600  {
1601  sal_Int32 index;
1602  for(index = 0; index < getLength() ; index++)
1603  {
1604  if(pData->buffer[ index ] != c)
1605  {
1606  break;
1607  }
1608  }
1609  if(index)
1610  {
1611  remove(0, index);
1612  }
1613  return index;
1614  }
1615 
1625  sal_Int32 stripEnd(sal_Unicode c = ' ')
1626  {
1627  sal_Int32 result = getLength();
1628  sal_Int32 index;
1629  for(index = getLength(); index > 0 ; index--)
1630  {
1631  if(pData->buffer[ index - 1 ] != c)
1632  {
1633  break;
1634  }
1635  }
1636  if(index < getLength())
1637  {
1638  truncate(index);
1639  }
1640  return result - getLength();
1641  }
1651  sal_Int32 strip(sal_Unicode c = ' ')
1652  {
1653  return stripStart(c) + stripEnd(c);
1654  }
1655 
1656 #if defined LIBO_INTERNAL_ONLY
1667  SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex ) const
1668  {
1669  assert(beginIndex >= 0);
1670  assert(beginIndex <= getLength());
1671  return subView(beginIndex, getLength() - beginIndex);
1672  }
1673 
1686  SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex, sal_Int32 count ) const
1687  {
1688  assert(beginIndex >= 0);
1689  assert(count >= 0);
1690  assert(beginIndex <= getLength());
1691  assert(count <= getLength() - beginIndex);
1692  return std::u16string_view(pData->buffer, sal_uInt32(pData->length)).substr(beginIndex, count);
1693  }
1694 #endif
1695 
1707  OUStringBuffer copy( sal_Int32 beginIndex ) const
1708  {
1709  return copy( beginIndex, getLength() - beginIndex );
1710  }
1711 
1725  OUStringBuffer copy( sal_Int32 beginIndex, sal_Int32 count ) const
1726  {
1727  assert(beginIndex >= 0 && beginIndex <= getLength());
1728  assert(count >= 0 && count <= getLength() - beginIndex);
1729  rtl_uString *pNew = NULL;
1730  rtl_uStringbuffer_newFromStr_WithLength( &pNew, getStr() + beginIndex, count );
1731  return OUStringBuffer( pNew, count + 16 );
1732  }
1733 
1734 private:
1735  OUStringBuffer( rtl_uString * value, const sal_Int32 capacity )
1736  {
1737  pData = value;
1738  nCapacity = capacity;
1739  }
1740 
1744  rtl_uString * pData;
1745 
1749  sal_Int32 nCapacity;
1750 };
1751 
1752 #if defined LIBO_INTERNAL_ONLY
1753 template<> struct ToStringHelper<OUStringBuffer> {
1754  static std::size_t length(OUStringBuffer const & s) { return s.getLength(); }
1755 
1756  static sal_Unicode * addData(sal_Unicode * buffer, OUStringBuffer const & s) SAL_RETURNS_NONNULL
1757  { return addDataHelper(buffer, s.getStr(), s.getLength()); }
1758 
1759  static constexpr bool allowOStringConcat = false;
1760  static constexpr bool allowOUStringConcat = true;
1761 };
1762 #endif
1763 
1764 #if defined LIBO_INTERNAL_ONLY
1765  // Define this here to avoid circular includes
1766  inline OUString & OUString::operator+=( const OUStringBuffer & str ) &
1767  {
1768  // Call operator= if this is empty, otherwise rtl_uString_newConcat will attempt to
1769  // acquire() the str.pData buffer, which is part of the OUStringBuffer mutable state.
1770  if (isEmpty())
1771  return operator=(str.toString());
1772  else
1773  return internalAppend(str.pData);
1774  }
1775 
1776  inline OUString const& OUString::unacquired(const OUStringBuffer& str)
1777  {
1778  return unacquired(&str.pData);
1779  }
1780 #endif
1781 }
1782 
1783 #ifdef RTL_STRING_UNITTEST
1784 namespace rtl
1785 {
1786 typedef rtlunittest::OUStringBuffer OUStringBuffer;
1787 }
1788 #endif
1789 
1790 #if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
1791 using ::rtl::OUStringBuffer;
1792 #endif
1793 
1794 #endif // INCLUDED_RTL_USTRBUF_HXX
1795 
1796 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define SAL_DEPRECATED(message)
Use as follows: SAL_DEPRECATED("Don't use, it's evil.") void doit(int nPara);.
Definition: types.h:474
#define SAL_DELETED_FUNCTION
short-circuit extra-verbose API namespaces
Definition: types.h:378
@ SAL_NO_ACQUIRE
definition of a no acquire enum for ctors
Definition: types.h:356
unsigned char sal_Bool
Definition: types.h:38
sal_uInt16 sal_Unicode
Definition: types.h:123
#define SAL_WARN_UNUSED_RESULT
Use this as markup for functions and methods whose return value must be checked.
Definition: types.h:284
#define SAL_WARN_UNUSED
Annotate classes where a compiler should warn if an instance is unused.
Definition: types.h:587
SAL_DLLPUBLIC sal_Int32 rtl_str_getLength(const char *str) SAL_THROW_EXTERN_C()
Return the length of a string.
SAL_DLLPUBLIC void rtl_uStringbuffer_insert_ascii(rtl_uString **This, sal_Int32 *capacity, sal_Int32 offset, const char *str, sal_Int32 len)
Inserts the 8-Bit ASCII string representation of the str array argument into this string buffer.
SAL_DLLPUBLIC void rtl_uStringbuffer_remove(rtl_uString **This, sal_Int32 start, sal_Int32 len)
Removes the characters in a substring of this sequence.
SAL_DLLPUBLIC void rtl_uStringbuffer_insertUtf32(rtl_uString **pThis, sal_Int32 *capacity, sal_Int32 offset, sal_uInt32 c) SAL_THROW_EXTERN_C()
Inserts a single UTF-32 character into this string buffer.
SAL_DLLPUBLIC void rtl_uStringbuffer_newFromStr_WithLength(rtl_uString **newStr, const sal_Unicode *value, sal_Int32 count)
Allocates a new String that contains characters from the character array argument.
SAL_DLLPUBLIC rtl_uString * rtl_uStringBuffer_makeStringAndClear(rtl_uString **ppThis, sal_Int32 *nCapacity) SAL_RETURNS_NONNULL
Returns an immutable rtl_uString object, while clearing the string buffer.
SAL_DLLPUBLIC sal_Int32 rtl_uStringbuffer_newFromStringBuffer(rtl_uString **newStr, sal_Int32 capacity, rtl_uString *oldStr)
Allocates a new String that contains the same sequence of characters as the string argument.
SAL_DLLPUBLIC void rtl_uStringbuffer_ensureCapacity(rtl_uString **This, sal_Int32 *capacity, sal_Int32 minimumCapacity)
Ensures that the capacity of the buffer is at least equal to the specified minimum.
SAL_DLLPUBLIC void rtl_uStringbuffer_insert(rtl_uString **This, sal_Int32 *capacity, sal_Int32 offset, const sal_Unicode *str, sal_Int32 len)
Inserts the string representation of the str array argument into this string buffer.
SAL_DLLPUBLIC void rtl_uString_new(rtl_uString **newStr) SAL_THROW_EXTERN_C()
Allocate a new string containing no characters.
#define RTL_USTR_MAX_VALUEOFFLOAT
Definition: ustring.h:1026
#define RTL_USTR_MAX_VALUEOFDOUBLE
Definition: ustring.h:1045
SAL_DLLPUBLIC void rtl_uString_newFromLiteral(rtl_uString **newStr, const char *value, sal_Int32 len, sal_Int32 allocExtra) SAL_THROW_EXTERN_C()
SAL_DLLPUBLIC sal_Int32 rtl_ustr_valueOfBoolean(sal_Unicode *str, sal_Bool b) SAL_THROW_EXTERN_C()
Create the string representation of a boolean.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_valueOfFloat(sal_Unicode *str, float f) SAL_THROW_EXTERN_C()
Create the string representation of a float.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_valueOfDouble(sal_Unicode *str, double d) SAL_THROW_EXTERN_C()
Create the string representation of a double.
#define RTL_USTR_MAX_VALUEOFINT64
Definition: ustring.h:984
SAL_DLLPUBLIC rtl_uString * rtl_uString_alloc(sal_Int32 nLen) SAL_THROW_EXTERN_C()
Allocate a new string containing space for a given number of characters.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_indexOfStr_WithLength(const sal_Unicode *str, sal_Int32 len, const sal_Unicode *subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
Search for the first occurrence of a substring within a string.
SAL_DLLPUBLIC void rtl_uString_release(rtl_uString *str) SAL_THROW_EXTERN_C() SAL_HOT
Decrement the reference count of a string.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_getLength(const sal_Unicode *str) SAL_THROW_EXTERN_C()
Return the length of a string.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_valueOfInt64(sal_Unicode *str, sal_Int64 l, sal_Int16 radix) SAL_THROW_EXTERN_C()
Create the string representation of a long integer.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength(sal_Unicode const *str, sal_Int32 len, char const *subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
Search for the last occurrence of an ASCII substring within a string.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_indexOfAscii_WithLength(sal_Unicode const *str, sal_Int32 len, char const *subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
Search for the first occurrence of an ASCII substring within a string.
SAL_DLLPUBLIC void rtl_uString_new_WithLength(rtl_uString **newStr, sal_Int32 nLen) SAL_THROW_EXTERN_C()
Allocate a new string containing space for a given number of characters.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_lastIndexOfChar_WithLength(const sal_Unicode *str, sal_Int32 len, sal_Unicode ch) SAL_THROW_EXTERN_C()
Search for the last occurrence of a character within a string.
#define RTL_USTR_MAX_VALUEOFBOOLEAN
Definition: ustring.h:919
SAL_DLLPUBLIC sal_Int32 rtl_ustr_valueOfInt32(sal_Unicode *str, sal_Int32 i, sal_Int16 radix) SAL_THROW_EXTERN_C()
Create the string representation of an integer.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_lastIndexOfStr_WithLength(const sal_Unicode *str, sal_Int32 len, const sal_Unicode *subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
Search for the last occurrence of a substring within a string.
SAL_DLLPUBLIC sal_Int32 rtl_ustr_indexOfChar_WithLength(const sal_Unicode *str, sal_Int32 len, sal_Unicode ch) SAL_THROW_EXTERN_C()
Search for the first occurrence of a character within a string.
#define RTL_USTR_MAX_VALUEOFINT32
Definition: ustring.h:961
Definition: bootstrap.hxx:34
Definition: stringutils.hxx:140
Definition: stringutils.hxx:143
Definition: stringutils.hxx:375
A string buffer implements a mutable sequence of characters.
Definition: ustrbuf.hxx:71
sal_Int32 lastIndexOf(sal_Unicode ch, sal_Int32 fromIndex) const
Returns the index within this string of the last occurrence of the specified character,...
Definition: ustrbuf.hxx:1421
sal_Int32 stripStart(sal_Unicode c=' ')
Strip the given character from the start of the buffer.
Definition: ustrbuf.hxx:1599
OUStringBuffer & appendUtf32(sal_uInt32 c)
Appends a single UTF-32 character to this string buffer.
Definition: ustrbuf.hxx:952
OUStringBuffer copy(sal_Int32 beginIndex) const
Returns a new string buffer that is a substring of this string.
Definition: ustrbuf.hxx:1707
OUStringBuffer & append(const OUStringBuffer &str)
Appends the content of a stringbuffer to this string buffer.
Definition: ustrbuf.hxx:618
OUStringBuffer & replace(sal_Unicode oldChar, sal_Unicode newChar)
Replace all occurrences of oldChar in this string buffer with newChar.
Definition: ustrbuf.hxx:1336
bool isEmpty() const
Checks if a string buffer is empty.
Definition: ustrbuf.hxx:431
OUStringBuffer & insert(sal_Int32 offset, const OUString &str)
Inserts the string into this string buffer.
Definition: ustrbuf.hxx:998
OUStringBuffer copy(sal_Int32 beginIndex, sal_Int32 count) const
Returns a new string buffer that is a substring of this string.
Definition: ustrbuf.hxx:1725
OUStringBuffer & insert(sal_Int32 offset, const sal_Unicode *str)
Inserts the string representation of the char array argument into this string buffer.
Definition: ustrbuf.hxx:1021
sal_Int32 getCapacity() const
Returns the current capacity of the String buffer.
Definition: ustrbuf.hxx:446
sal_Int32 getLength() const
Returns the length (character count) of this string buffer.
Definition: ustrbuf.hxx:418
OUStringBuffer & append(rtl_uString *str)
Definition: ustrbuf.hxx:810
OUStringBuffer & append(float f)
Appends the string representation of the float argument to this string buffer.
Definition: ustrbuf.hxx:916
OUStringBuffer & append(double d)
Appends the string representation of the double argument to this string buffer.
Definition: ustrbuf.hxx:933
OUStringBuffer & append(const sal_Unicode *str)
Appends the string representation of the char array argument to this string buffer.
Definition: ustrbuf.hxx:644
OUStringBuffer & appendAscii(const char *str, sal_Int32 len)
Appends a 8-Bit ASCII character string to this string buffer.
Definition: ustrbuf.hxx:770
sal_Int32 strip(sal_Unicode c=' ')
Strip the given character from the both end of the buffer.
Definition: ustrbuf.hxx:1651
OUStringBuffer()
Constructs a string buffer with no characters in it and an initial capacity of 16 characters.
Definition: ustrbuf.hxx:78
OUStringBuffer & insertUtf32(sal_Int32 offset, sal_uInt32 c)
Inserts a single UTF-32 character into this string buffer.
Definition: ustrbuf.hxx:1287
OUStringBuffer & append(sal_Int64 l, sal_Int16 radix=10)
Appends the string representation of the long argument to this string buffer.
Definition: ustrbuf.hxx:899
sal_Int32 indexOf(const OUString &str, sal_Int32 fromIndex=0) const
Returns the index within this string of the first occurrence of the specified substring,...
Definition: ustrbuf.hxx:1453
const sal_Unicode * getStr() const SAL_RETURNS_NONNULL
Return a null terminated unicode character array.
Definition: ustrbuf.hxx:540
OUStringBuffer & append(const OUString &str)
Appends the string to this string buffer.
Definition: ustrbuf.hxx:592
OUStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix=10)
Inserts the string representation of the long argument into this string buffer.
Definition: ustrbuf.hxx:1218
OUStringBuffer & appendAscii(const char *str)
Appends a 8-Bit ASCII character string to this string buffer.
Definition: ustrbuf.hxx:747
void setLength(sal_Int32 newLength)
Sets the length of this String buffer.
Definition: ustrbuf.hxx:485
OUStringBuffer(const OUStringBuffer &value)
Allocates a new string buffer that contains the same sequence of characters as the string buffer argu...
Definition: ustrbuf.hxx:91
OUStringBuffer & insert(sal_Int32 offset, const sal_Unicode *str, sal_Int32 len)
Inserts the string representation of the char array argument into this string buffer.
Definition: ustrbuf.hxx:1044
OUStringBuffer(T &literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type=libreoffice_internal::Dummy())
Definition: ustrbuf.hxx:162
sal_Int32 indexOf(sal_Unicode ch, sal_Int32 fromIndex=0) const
Returns the index within this string of the first occurrence of the specified character,...
Definition: ustrbuf.hxx:1384
OUStringBuffer & insert(sal_Int32 offset, double d)
Inserts the string representation of the double argument into this string buffer.
Definition: ustrbuf.hxx:1266
OUString toString() const
Return an OUString instance reflecting the current content of this OUStringBuffer.
Definition: ustrbuf.hxx:576
OUStringBuffer & append(const sal_Unicode *str, sal_Int32 len)
Appends the string representation of the char array argument to this string buffer.
Definition: ustrbuf.hxx:663
OUStringBuffer(sal_Int32 length)
Constructs a string buffer with no characters in it and an initial capacity specified by the length a...
Definition: ustrbuf.hxx:104
OUStringBuffer insert(sal_Int32 offset, float f)
Inserts the string representation of the float argument into this string buffer.
Definition: ustrbuf.hxx:1242
sal_Int32 lastIndexOf(const OUString &str, sal_Int32 fromIndex) const
Returns the index within this string of the last occurrence of the specified substring,...
Definition: ustrbuf.hxx:1553
sal_Int32 stripEnd(sal_Unicode c=' ')
Strip the given character from the end of the buffer.
Definition: ustrbuf.hxx:1625
OUStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix=10)
Inserts the string representation of the second sal_Int32 argument into this string buffer.
Definition: ustrbuf.hxx:1193
OUStringBuffer & append(sal_Unicode c)
Appends the string representation of the char argument to this string buffer.
Definition: ustrbuf.hxx:860
OUStringBuffer & remove(sal_Int32 start, sal_Int32 len)
Removes the characters in a substring of this sequence.
Definition: ustrbuf.hxx:1304
libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf(T &literal, sal_Int32 fromIndex=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ustrbuf.hxx:1469
libreoffice_internal::ConstCharArrayDetector< T, OUStringBuffer & >::Type append(T &literal)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ustrbuf.hxx:676
OUStringBuffer & insert(sal_Int32 offset, char c)
Inserts the string representation of the char argument into this string buffer.
Definition: ustrbuf.hxx:1147
OUStringBuffer & truncate(sal_Int32 start=0)
Removes the tail of a string buffer start at the indicate position.
Definition: ustrbuf.hxx:1320
sal_Int32 lastIndexOf(sal_Unicode ch) const
Returns the index within this string of the last occurrence of the specified character,...
Definition: ustrbuf.hxx:1402
OUStringBuffer(const OUString &value)
Constructs a string buffer so that it represents the same sequence of characters as the string argume...
Definition: ustrbuf.hxx:153
~OUStringBuffer()
Release the string data.
Definition: ustrbuf.hxx:393
libreoffice_internal::ConstCharArrayDetector< T, OUStringBuffer & >::Type insert(sal_Int32 offset, T &literal)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ustrbuf.hxx:1057
libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf(T &literal) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ustrbuf.hxx:1567
void ensureCapacity(sal_Int32 minimumCapacity)
Ensures that the capacity of the buffer is at least equal to the specified minimum.
Definition: ustrbuf.hxx:462
OUStringBuffer & insert(sal_Int32 offset, sal_Bool b)
Inserts the string representation of the sal_Bool argument into this string buffer.
Definition: ustrbuf.hxx:1098
OUStringBuffer & append(char c)
Appends the string representation of the ASCII char argument to this string buffer.
Definition: ustrbuf.hxx:844
OUStringBuffer & insert(sal_Int32 offset, sal_Unicode c)
Inserts the string representation of the char argument into this string buffer.
Definition: ustrbuf.hxx:1169
OUStringBuffer & insert(sal_Int32 offset, bool b)
Inserts the string representation of the bool argument into this string buffer.
Definition: ustrbuf.hxx:1123
OUStringBuffer & append(sal_Int32 i, sal_Int16 radix=10)
Appends the string representation of the sal_Int32 argument to this string buffer.
Definition: ustrbuf.hxx:881
sal_Int32 lastIndexOf(const OUString &str) const
Returns the index within this string of the last occurrence of the specified substring,...
Definition: ustrbuf.hxx:1519
OUStringBuffer & append(sal_Bool b)
Appends the string representation of the sal_Bool argument to the string buffer.
Definition: ustrbuf.hxx:826
SAL_WARN_UNUSED_RESULT OUString makeStringAndClear()
Fill the string data in the new string and clear the buffer.
Definition: ustrbuf.hxx:406
sal_Unicode * appendUninitialized(sal_Int32 length) SAL_RETURNS_NONNULL
Unsafe way to make space for a fixed amount of characters to be appended into this OUStringBuffer.
Definition: ustrbuf.hxx:971
void accessInternals(rtl_uString ***pInternalData, sal_Int32 **pInternalCapacity)
Allows access to the internal data of this OUStringBuffer, for effective manipulation.
Definition: ustrbuf.hxx:1361
OUStringBuffer & append(bool b)
Appends the string representation of the bool argument to the string buffer.
Definition: ustrbuf.hxx:789
This String class provides base functionality for C++ like Unicode character array handling.
Definition: ustring.hxx:203
const sal_Unicode * getStr() const SAL_RETURNS_NONNULL
Returns a pointer to the Unicode character buffer for this string.
Definition: ustring.hxx:829
OUString & operator+=(const OUString &str)
Append a string to this string.
Definition: ustring.hxx:678
sal_Int32 getLength() const
Returns the length of this string.
Definition: ustring.hxx:807
static OUString const & unacquired(rtl_uString *const *ppHandle)
Provides an OUString const & passing a storage pointer of an rtl_uString * handle.
Definition: ustring.hxx:540