1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_USTRBUF_HXX
21#define INCLUDED_RTL_USTRBUF_HXX
22
23#include <sal/config.h>
24
25#include <cassert>
26#include <string.h>
27
28#include <osl/diagnose.h>
29#include <rtl/ustrbuf.h>
30#include <rtl/ustring.hxx>
31#include <rtl/stringutils.hxx>
32#include <sal/types.h>
33
34#ifdef RTL_FAST_STRING
35#include <rtl/stringconcat.hxx>
36#endif
37
38// The unittest uses slightly different code to help check that the proper
39// calls are made. The class is put into a different namespace to make
40// sure the compiler generates a different (if generating also non-inline)
41// copy of the function and does not merge them together. The class
42// is "brought" into the proper rtl namespace by a typedef below.
43#ifdef RTL_STRING_UNITTEST
44#define rtl rtlunittest
45#endif
46
47namespace rtl
48{
49
50#ifdef RTL_STRING_UNITTEST
51#undef rtl
52#endif
53
54/** A string buffer implements a mutable sequence of characters.
55 <p>
56 String buffers are safe for use by multiple threads. The methods
57 are synchronized where necessary so that all the operations on any
58 particular instance behave as if they occur in some serial order.
59 <p>
60 String buffers are used by the compiler to implement the binary
61 string concatenation operator <code>+</code>. For example, the code:
62 <p><blockquote><pre>
63 x = "a" + 4 + "c"
64 </pre></blockquote><p>
65 is compiled to the equivalent of:
66 <p><blockquote><pre>
67 x = new OUStringBuffer().append("a").append(4).append("c")
68 .makeStringAndClear()
69 </pre></blockquote><p>
70 The principal operations on a <code>OUStringBuffer</code> are the
71 <code>append</code> and <code>insert</code> methods, which are
72 overloaded so as to accept data of any type. Each effectively
73 converts a given datum to a string and then appends or inserts the
74 characters of that string to the string buffer. The
75 <code>append</code> method always adds these characters at the end
76 of the buffer; the <code>insert</code> method adds the characters at
77 a specified point.
78 <p>
79 For example, if <code>z</code> refers to a string buffer object
80 whose current contents are "<code>start</code>", then
81 the method call <code>z.append("le")</code> would cause the string
82 buffer to contain "<code>startle</code>", whereas
83 <code>z.insert(4, "le")</code> would alter the string buffer to
84 contain "<code>starlet</code>".
85 <p>
86 Every string buffer has a capacity. As long as the length of the
87 character sequence contained in the string buffer does not exceed
88 the capacity, it is not necessary to allocate a new internal
89 buffer array. If the internal buffer overflows, it is
90 automatically made larger.
91 */
92class SAL_WARN_UNUSED OUStringBuffer
93{
94public:
95 /**
96 Constructs a string buffer with no characters in it and an
97 initial capacity of 16 characters.
98 */
99 OUStringBuffer()
100 : pData(NULL)
101 , nCapacity( 16 )
102 {
103 rtl_uString_new_WithLength( &pData, nCapacity );
104 }
105
106 /**
107 Allocates a new string buffer that contains the same sequence of
108 characters as the string buffer argument.
109
110 @param value a <code>OUStringBuffer</code>.
111 */
112 OUStringBuffer( const OUStringBuffer & value )
113 : pData(NULL)
114 , nCapacity( value.nCapacity )
115 {
116 rtl_uStringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
117 }
118
119 /**
120 Constructs a string buffer with no characters in it and an
121 initial capacity specified by the <code>length</code> argument.
122
123 @param length the initial capacity.
124 */
125 explicit OUStringBuffer(int length)
126 : pData(NULL)
127 , nCapacity( length )
128 {
129 rtl_uString_new_WithLength( &pData, length );
130 }
131
132 /**
133 Constructs a string buffer so that it represents the same
134 sequence of characters as the string argument.
135
136 The initial
137 capacity of the string buffer is <code>16</code> plus the length
138 of the string argument.
139
140 @param value the initial contents of the buffer.
141 */
142 OUStringBuffer(const OUString& value)
143 : pData(NULL)
144 , nCapacity( value.getLength() + 16 )
145 {
146 rtl_uStringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
147 }
148
149 template< typename T >
150 OUStringBuffer( T& literal, typename internal::ConstCharArrayDetector< T, internal::Dummy >::Type = internal::Dummy() )
151 : pData(NULL)
152 , nCapacity( internal::ConstCharArrayDetector< T, void >::size - 1 + 16 )
153 {
154 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
155 rtl_uString_newFromLiteral( &pData, literal, internal::ConstCharArrayDetector< T, void >::size - 1, 16 );
156#ifdef RTL_STRING_UNITTEST
157 rtl_string_unittest_const_literal = true;
158#endif
159 }
160
161#ifdef RTL_STRING_UNITTEST
162 /**
163 * Only used by unittests to detect incorrect conversions.
164 * @internal
165 */
166 template< typename T >
167 OUStringBuffer( T&, typename internal::ExceptConstCharArrayDetector< T >::Type = internal::Dummy() )
168 {
169 pData = 0;
170 nCapacity = 10;
171 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
172 rtl_string_unittest_invalid_conversion = true;
173 }
174 /**
175 * Only used by unittests to detect incorrect conversions.
176 * @internal
177 */
178 template< typename T >
179 OUStringBuffer( const T&, typename internal::ExceptCharArrayDetector< T >::Type = internal::Dummy() )
180 {
181 pData = 0;
182 nCapacity = 10;
183 rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
184 rtl_string_unittest_invalid_conversion = true;
185 }
186#endif
187
188#ifdef RTL_FAST_STRING
189 /**
190 @overload
191 @internal
192 */
193 template< typename T1, typename T2 >
194 OUStringBuffer( const OUStringConcat< T1, T2 >& c )
195 {
196 const sal_Int32 l = c.length();
197 nCapacity = l + 16;
198 pData = rtl_uString_alloc( nCapacity );
199 sal_Unicode* end = c.addData( pData->buffer );
200 *end = '\0';
201 pData->length = end - pData->buffer;
202 // TODO realloc in case pData->>length is noticeably smaller than l ?
203 }
204#endif
205 /** Assign to this a copy of value.
206 */
207 OUStringBuffer& operator = ( const OUStringBuffer& value )
208 {
209 if (this != &value)
210 {
211 rtl_uStringbuffer_newFromStringBuffer(&pData,
212 value.nCapacity,
213 value.pData);
214 nCapacity = value.nCapacity;
215 }
216 return *this;
217 }
218
219 /**
220 Release the string data.
221 */
222 ~OUStringBuffer()
223 {
224 rtl_uString_release( pData );
225 }
226
227 /**
228 Fill the string data in the new string and clear the buffer.
229
230 This method is more efficient than the contructor of the string. It does
231 not copy the buffer.
232
233 @return the string previously contained in the buffer.
234 */
235 OUString makeStringAndClear()
236 {
237 return OUString(
238 rtl_uStringBuffer_makeStringAndClear( &pData, &nCapacity ),
239 SAL_NO_ACQUIRE );
240 }
241
242 /**
243 Returns the length (character count) of this string buffer.
244
245 @return the number of characters in this string buffer.
246 */
247 sal_Int32 getLength() const
248 {
249 return pData->length;
250 }
251
252 /**
253 Checks if a string buffer is empty.
254
255 @return true if the string buffer is empty;
256 false, otherwise.
257
258 @since LibreOffice 4.1
259 */
260 bool isEmpty() const SAL_THROW(())
261 {
262 return pData->length == 0;
263 }
264
265 /**
266 Returns the current capacity of the String buffer.
267
268 The capacity
269 is the amount of storage available for newly inserted
270 characters. The real buffer size is 2 bytes longer, because
271 all strings are 0 terminated.
272
273 @return the current capacity of this string buffer.
274 */
275 sal_Int32 getCapacity() const
276 {
277 return nCapacity;
278 }
279
280 /**
281 Ensures that the capacity of the buffer is at least equal to the
282 specified minimum.
283
284 The new capacity will be at least as large as the maximum of the current
285 length (so that no contents of the buffer is destroyed) and the given
286 minimumCapacity. If the given minimumCapacity is negative, nothing is
287 changed.
288
289 @param minimumCapacity the minimum desired capacity.
290 */
291 void ensureCapacity(sal_Int32 minimumCapacity)
292 {
293 rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
294 }
295
296 /**
297 Sets the length of this String buffer.
298
299 If the <code>newLength</code> argument is less than the current
300 length of the string buffer, the string buffer is truncated to
301 contain exactly the number of characters given by the
302 <code>newLength</code> argument.
303 <p>
304 If the <code>newLength</code> argument is greater than or equal
305 to the current length, sufficient null characters
306 (<code>'&#92;u0000'</code>) are appended to the string buffer so that
307 length becomes the <code>newLength</code> argument.
308 <p>
309 The <code>newLength</code> argument must be greater than or equal
310 to <code>0</code>.
311
312 @param newLength the new length of the buffer.
313 */
314 void setLength(sal_Int32 newLength)
315 {
316 assert(newLength >= 0);
317 // Avoid modifications if pData points to const empty string:
318 if( newLength != pData->length )
319 {
320 if( newLength > nCapacity )
321 rtl_uStringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
322 else
323 pData->buffer[newLength] = 0;
324 pData->length = newLength;
325 }
326 }
327
328 /**
329 Returns the character at a specific index in this string buffer.
330
331 The first character of a string buffer is at index
332 <code>0</code>, the next at index <code>1</code>, and so on, for
333 array indexing.
334 <p>
335 The index argument must be greater than or equal to
336 <code>0</code>, and less than the length of this string buffer.
337
338 @param index the index of the desired character.
339 @return the character at the specified index of this string buffer.
340 */
341 SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
342 sal_Unicode charAt( sal_Int32 index ) const
343 {
344 assert(index >= 0 && index < pData->length);
345 return pData->buffer[ index ];
346 }
347
348 /**
349 The character at the specified index of this string buffer is set
350 to <code>ch</code>.
351
352 The index argument must be greater than or equal to
353 <code>0</code>, and less than the length of this string buffer.
354
355 @param index the index of the character to modify.
356 @param ch the new character.
357 */
358 SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
359 OUStringBuffer & setCharAt(sal_Int32 index, sal_Unicode ch)
360 {
361 assert(index >= 0 && index < pData->length);
362 pData->buffer[ index ] = ch;
363 return *this;
364 }
365
366 /**
367 Return a null terminated unicode character array.
368 */
369 const sal_Unicode* getStr() const { return pData->buffer; }
370
371 /**
372 Access to individual characters.
373
374 @param index must be non-negative and less than length.
375
376 @return a reference to the character at the given index.
377
378 @since LibreOffice 3.5
379 */
380 sal_Unicode & operator [](sal_Int32 index)
381 {
382 assert(index >= 0 && index < pData->length);
383 return pData->buffer[index];
384 }
385
386 /**
387 Access to individual characters.
388
389 @param index must be non-negative and less than length.
390
391 @return a reference to the character at the given index.
392
393 @since LibreOffice 4.2
394 */
395 const sal_Unicode & operator [](sal_Int32 index) const
396 {
397 assert(index >= 0 && index < pData->length);
398 return pData->buffer[index];
399 }
400
401 /**
402 Return a OUString instance reflecting the current content
403 of this OUStringBuffer.
404 */
405 const OUString toString() const
406 {
407 return OUString(pData->buffer, pData->length);
408 }
409
410 /**
411 Appends the string to this string buffer.
412
413 The characters of the <code>OUString</code> argument are appended, in
414 order, to the contents of this string buffer, increasing the
415 length of this string buffer by the length of the argument.
416
417 @param str a string.
418 @return this string buffer.
419 */
420 OUStringBuffer & append(const OUString &str)
421 {
422 return append( str.getStr(), str.getLength() );
423 }
424
425 /**
426 Appends the content of a stringbuffer to this string buffer.
427
428 The characters of the <code>OUStringBuffer</code> argument are appended, in
429 order, to the contents of this string buffer, increasing the
430 length of this string buffer by the length of the argument.
431
432 @param str a string.
433 @return this string buffer.
434
435 @since LibreOffice 4.0
436 */
437 OUStringBuffer & append(const OUStringBuffer &str)
438 {
439 if(!str.isEmpty())
440 {
441 append( str.getStr(), str.getLength() );
442 }
443 return *this;
444 }
445
446 /**
447 Appends the string representation of the <code>char</code> array
448 argument to this string buffer.
449
450 The characters of the array argument are appended, in order, to
451 the contents of this string buffer. The length of this string
452 buffer increases by the length of the argument.
453
454 @param str the characters to be appended.
455 @return this string buffer.
456 */
457 OUStringBuffer & append( const sal_Unicode * str )
458 {
459 return append( str, rtl_ustr_getLength( str ) );
460 }
461
462 /**
463 Appends the string representation of the <code>char</code> array
464 argument to this string buffer.
465
466 Characters of the character array <code>str</code> are appended,
467 in order, to the contents of this string buffer. The length of this
468 string buffer increases by the value of <code>len</code>.
469
470 @param str the characters to be appended; must be non-null, and must
471 point to at least len characters
472 @param len the number of characters to append; must be non-negative
473 @return this string buffer.
474 */
475 OUStringBuffer & append( const sal_Unicode * str, sal_Int32 len)
476 {
477 // insert behind the last character
478 rtl_uStringbuffer_insert( &pData, &nCapacity, getLength(), str, len );
479 return *this;
480 }
481
482 /**
483 @overload
484 This function accepts an ASCII string literal as its argument.
485 @since LibreOffice 3.6
486 */
487 template< typename T >
488 typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
489 {
490 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
491 rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), literal,
492 internal::ConstCharArrayDetector< T, void >::size - 1 );
493 return *this;
494 }
495
496#ifdef RTL_FAST_STRING
497 /**
498 @overload
499 @internal
500 */
501 template< typename T1, typename T2 >
502 OUStringBuffer& append( const OUStringConcat< T1, T2 >& c )
503 {
504 const int l = c.length();
505 if( l == 0 )
506 return *this;
507 rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, pData->length + l );
508 sal_Unicode* end = c.addData( pData->buffer + pData->length );
509 *end = '\0';
510 pData->length = end - pData->buffer;
511 return *this;
512 }
513#endif
514
515 /**
516 Appends a 8-Bit ASCII character string to this string buffer.
517
518 Since this method is optimized for performance. the ASCII
519 character values are not converted in any way. The caller
520 has to make sure that all ASCII characters are in the
521 allowed range between 0 and 127. The ASCII string must be
522 NULL-terminated.
523 <p>
524 The characters of the array argument are appended, in order, to
525 the contents of this string buffer. The length of this string
526 buffer increases by the length of the argument.
527
528 @param str the 8-Bit ASCII characters to be appended.
529 @return this string buffer.
530 */
531 OUStringBuffer & appendAscii( const sal_Char * str )
532 {
533 return appendAscii( str, rtl_str_getLength( str ) );
534 }
535
536 /**
537 Appends a 8-Bit ASCII character string to this string buffer.
538
539 Since this method is optimized for performance. the ASCII
540 character values are not converted in any way. The caller
541 has to make sure that all ASCII characters are in the
542 allowed range between 0 and 127. The ASCII string must be
543 NULL-terminated.
544 <p>
545 Characters of the character array <code>str</code> are appended,
546 in order, to the contents of this string buffer. The length of this
547 string buffer increases by the value of <code>len</code>.
548
549 @param str the 8-Bit ASCII characters to be appended; must be non-null,
550 and must point to at least len characters
551 @param len the number of characters to append; must be non-negative
552 @return this string buffer.
553 */
554 OUStringBuffer & appendAscii( const sal_Char * str, sal_Int32 len)
555 {
556 rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), str, len );
557 return *this;
558 }
559
560 /**
561 Appends the string representation of the <code>bool</code>
562 argument to the string buffer.
563
564 The argument is converted to a string as if by the method
565 <code>String.valueOf</code>, and the characters of that
566 string are then appended to this string buffer.
567
568 @param b a <code>bool</code>.
569 @return this string buffer.
570
571 @since LibreOffice 4.1
572 */
573 OUStringBuffer & append(bool b)
574 {
575 sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
576 return append( sz, rtl_ustr_valueOfBoolean( sz, b ) );
577 }
578
579 /// @cond INTERNAL
580 // Pointer can be automatically converted to bool, which is unwanted here.
581 // Explicitly delete all pointer append() overloads to prevent this
582 // (except for char* and sal_Unicode* overloads, which are handled elsewhere).
583 template< typename T >
584 typename internal::Enable< void,
585 !internal::CharPtrDetector< T* >::ok && !internal::SalUnicodePtrDetector< T* >::ok >::Type
586 append( T* ) SAL_DELETED_FUNCTION;
587 /// @endcond
588
589 // This overload is needed because OUString has a ctor from rtl_uString*, but
590 // the bool overload above would be preferred to the conversion.
591 /**
592 @internal
593 */
594 OUStringBuffer & append(rtl_uString* str)
595 {
596 return append( OUString( str ));
597 }
598
599 /**
600 Appends the string representation of the <code>sal_Bool</code>
601 argument to the string buffer.
602
603 The argument is converted to a string as if by the method
604 <code>String.valueOf</code>, and the characters of that
605 string are then appended to this string buffer.
606
607 @param b a <code>sal_Bool</code>.
608 @return this string buffer.
609 */
610 OUStringBuffer & append(sal_Bool b)
611 {
612 sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
613 return append( sz, rtl_ustr_valueOfBoolean( sz, b ) );
614 }
615
616 /**
617 Appends the string representation of the ASCII <code>char</code>
618 argument to this string buffer.
619
620 The argument is appended to the contents of this string buffer.
621 The length of this string buffer increases by <code>1</code>.
622
623 @param c an ASCII <code>char</code>.
624 @return this string buffer.
625
626 @since LibreOffice 3.5
627 */
628 OUStringBuffer & append(char c)
629 {
630 assert(static_cast< unsigned char >(c) <= 0x7F);
631 return append(sal_Unicode(c));
632 }
633
634 /**
635 Appends the string representation of the <code>char</code>
636 argument to this string buffer.
637
638 The argument is appended to the contents of this string buffer.
639 The length of this string buffer increases by <code>1</code>.
640
641 @param c a <code>char</code>.
642 @return this string buffer.
643 */
644 OUStringBuffer & append(sal_Unicode c)
645 {
646 return append( &c, 1 );
647 }
648
649 /**
650 Appends the string representation of the <code>sal_Int32</code>
651 argument to this string buffer.
652
653 The argument is converted to a string as if by the method
654 <code>String.valueOf</code>, and the characters of that
655 string are then appended to this string buffer.
656
657 @param i an <code>sal_Int32</code>.
658 @param radix the radix
659 @return this string buffer.
660 */
661 OUStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
662 {
663 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT32];
664 return append( sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
665 }
666
667 /**
668 Appends the string representation of the <code>long</code>
669 argument to this string buffer.
670
671 The argument is converted to a string as if by the method
672 <code>String.valueOf</code>, and the characters of that
673 string are then appended to this string buffer.
674
675 @param l a <code>long</code>.
676 @param radix the radix
677 @return this string buffer.
678 */
679 OUStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
680 {
681 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT64];
682 return append( sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
683 }
684
685 /**
686 Appends the string representation of the <code>float</code>
687 argument to this string buffer.
688
689 The argument is converted to a string as if by the method
690 <code>String.valueOf</code>, and the characters of that
691 string are then appended to this string buffer.
692
693 @param f a <code>float</code>.
694 @return this string buffer.
695 */
696 OUStringBuffer & append(float f)
697 {
698 sal_Unicode sz[RTL_USTR_MAX_VALUEOFFLOAT];
699 return append( sz, rtl_ustr_valueOfFloat( sz, f ) );
700 }
701
702 /**
703 Appends the string representation of the <code>double</code>
704 argument to this string buffer.
705
706 The argument is converted to a string as if by the method
707 <code>String.valueOf</code>, and the characters of that
708 string are then appended to this string buffer.
709
710 @param d a <code>double</code>.
711 @return this string buffer.
712 */
713 OUStringBuffer & append(double d)
714 {
715 sal_Unicode sz[RTL_USTR_MAX_VALUEOFDOUBLE];
716 return append( sz, rtl_ustr_valueOfDouble( sz, d ) );
717 }
718
719 /**
720 Appends a single UTF-32 character to this string buffer.
721
722 <p>The single UTF-32 character will be represented within the string
723 buffer as either one or two UTF-16 code units.</p>
724
725 @param c a well-formed UTF-32 code unit (that is, a value in the range
726 <code>0</code>&ndash;<code>0x10FFFF</code>, but excluding
727 <code>0xD800</code>&ndash;<code>0xDFFF</code>)
728
729 @return
730 this string buffer
731 */
732 OUStringBuffer & appendUtf32(sal_uInt32 c) {
733 return insertUtf32(getLength(), c);
734 }
735
736 /**
737 Inserts the string into this string buffer.
738
739 The characters of the <code>String</code> argument are inserted, in
740 order, into this string buffer at the indicated offset. The length
741 of this string buffer is increased by the length of the argument.
742 <p>
743 The offset argument must be greater than or equal to
744 <code>0</code>, and less than or equal to the length of this
745 string buffer.
746
747 @param offset the offset.
748 @param str a string.
749 @return this string buffer.
750 */
751 OUStringBuffer & insert(sal_Int32 offset, const OUString & str)
752 {
753 return insert( offset, str.getStr(), str.getLength() );
754 }
755
756 /**
757 Inserts the string representation of the <code>char</code> array
758 argument into this string buffer.
759
760 The characters of the array argument are inserted into the
761 contents of this string buffer at the position indicated by
762 <code>offset</code>. The length of this string buffer increases by
763 the length of the argument.
764 <p>
765 The offset argument must be greater than or equal to
766 <code>0</code>, and less than or equal to the length of this
767 string buffer.
768
769 @param offset the offset.
770 @param str a character array.
771 @return this string buffer.
772 */
773 OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str )
774 {
775 return insert( offset, str, rtl_ustr_getLength( str ) );
776 }
777
778 /**
779 Inserts the string representation of the <code>char</code> array
780 argument into this string buffer.
781
782 The characters of the array argument are inserted into the
783 contents of this string buffer at the position indicated by
784 <code>offset</code>. The length of this string buffer increases by
785 the length of the argument.
786 <p>
787 The offset argument must be greater than or equal to
788 <code>0</code>, and less than or equal to the length of this
789 string buffer.
790
791 @param offset the offset.
792 @param str a character array.
793 @param len the number of characters to append.
794 @return this string buffer.
795 */
796 OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str, sal_Int32 len)
797 {
798 // insert behind the last character
799 rtl_uStringbuffer_insert( &pData, &nCapacity, offset, str, len );
800 return *this;
801 }
802
803 /**
804 @overload
805 This function accepts an ASCII string literal as its argument.
806 @since LibreOffice 3.6
807 */
808 template< typename T >
809 typename internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
810 {
811 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
812 rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, offset, literal,
813 internal::ConstCharArrayDetector< T, void >::size - 1 );
814 return *this;
815 }
816
817 /**
818 Inserts the string representation of the <code>sal_Bool</code>
819 argument into this string buffer.
820
821 The second argument is converted to a string as if by the method
822 <code>String.valueOf</code>, and the characters of that
823 string are then inserted into this string buffer at the indicated
824 offset.
825 <p>
826 The offset argument must be greater than or equal to
827 <code>0</code>, and less than or equal to the length of this
828 string buffer.
829
830 @param offset the offset.
831 @param b a <code>sal_Bool</code>.
832 @return this string buffer.
833 */
834 OUStringBuffer & insert(sal_Int32 offset, sal_Bool b)
835 {
836 sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
837 return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
838 }
839
840 /**
841 Inserts the string representation of the <code>bool</code>
842 argument into this string buffer.
843
844 The second argument is converted to a string as if by the method
845 <code>OUString::boolean</code>, and the characters of that
846 string are then inserted into this string buffer at the indicated
847 offset.
848 <p>
849 The offset argument must be greater than or equal to
850 <code>0</code>, and less than or equal to the length of this
851 string buffer.
852
853 @param offset the offset.
854 @param b a <code>bool</code>.
855 @return this string buffer.
856
857 @since LibreOffice 4.3
858 */
859 OUStringBuffer & insert(sal_Int32 offset, bool b)
860 {
861 sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
862 return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
863 }
864
865 /**
866 Inserts the string representation of the <code>char</code>
867 argument into this string buffer.
868
869 The second argument is inserted into the contents of this string
870 buffer at the position indicated by <code>offset</code>. The length
871 of this string buffer increases by one.
872 <p>
873 The offset argument must be greater than or equal to
874 <code>0</code>, and less than or equal to the length of this
875 string buffer.
876
877 @param offset the offset.
878 @param c a <code>char</code>.
879 @return this string buffer.
880
881 @since LibreOffice 3.6
882 */
883 OUStringBuffer & insert(sal_Int32 offset, char c)
884 {
885 sal_Unicode u = c;
886 return insert( offset, &u, 1 );
887 }
888
889 /**
890 Inserts the string representation of the <code>char</code>
891 argument into this string buffer.
892
893 The second argument is inserted into the contents of this string
894 buffer at the position indicated by <code>offset</code>. The length
895 of this string buffer increases by one.
896 <p>
897 The offset argument must be greater than or equal to
898 <code>0</code>, and less than or equal to the length of this
899 string buffer.
900
901 @param offset the offset.
902 @param c a <code>char</code>.
903 @return this string buffer.
904 */
905 OUStringBuffer & insert(sal_Int32 offset, sal_Unicode c)
906 {
907 return insert( offset, &c, 1 );
908 }
909
910 /**
911 Inserts the string representation of the second <code>sal_Int32</code>
912 argument into this string buffer.
913
914 The second argument is converted to a string as if by the method
915 <code>String.valueOf</code>, and the characters of that
916 string are then inserted into this string buffer at the indicated
917 offset.
918 <p>
919 The offset argument must be greater than or equal to
920 <code>0</code>, and less than or equal to the length of this
921 string buffer.
922
923 @param offset the offset.
924 @param i an <code>sal_Int32</code>.
925 @param radix the radix.
926 @return this string buffer.
927 @exception StringIndexOutOfBoundsException if the offset is invalid.
928 */
929 OUStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
930 {
931 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT32];
932 return insert( offset, sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
933 }
934
935 /**
936 Inserts the string representation of the <code>long</code>
937 argument into this string buffer.
938
939 The second argument is converted to a string as if by the method
940 <code>String.valueOf</code>, and the characters of that
941 string are then inserted into this string buffer at the indicated
942 offset.
943 <p>
944 The offset argument must be greater than or equal to
945 <code>0</code>, and less than or equal to the length of this
946 string buffer.
947
948 @param offset the offset.
949 @param l a <code>long</code>.
950 @param radix the radix.
951 @return this string buffer.
952 @exception StringIndexOutOfBoundsException if the offset is invalid.
953 */
954 OUStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
955 {
956 sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT64];
957 return insert( offset, sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
958 }
959
960 /**
961 Inserts the string representation of the <code>float</code>
962 argument into this string buffer.
963
964 The second argument is converted to a string as if by the method
965 <code>String.valueOf</code>, and the characters of that
966 string are then inserted into this string buffer at the indicated
967 offset.
968 <p>
969 The offset argument must be greater than or equal to
970 <code>0</code>, and less than or equal to the length of this
971 string buffer.
972
973 @param offset the offset.
974 @param f a <code>float</code>.
975 @return this string buffer.
976 @exception StringIndexOutOfBoundsException if the offset is invalid.
977 */
978 OUStringBuffer insert(sal_Int32 offset, float f)
979 {
980 sal_Unicode sz[RTL_USTR_MAX_VALUEOFFLOAT];
981 return insert( offset, sz, rtl_ustr_valueOfFloat( sz, f ) );
982 }
983
984 /**
985 Inserts the string representation of the <code>double</code>
986 argument into this string buffer.
987
988 The second argument is converted to a string as if by the method
989 <code>String.valueOf</code>, and the characters of that
990 string are then inserted into this string buffer at the indicated
991 offset.
992 <p>
993 The offset argument must be greater than or equal to
994 <code>0</code>, and less than or equal to the length of this
995 string buffer.
996
997 @param offset the offset.
998 @param d a <code>double</code>.
999 @return this string buffer.
1000 @exception StringIndexOutOfBoundsException if the offset is invalid.
1001 */
1002 OUStringBuffer & insert(sal_Int32 offset, double d)
1003 {
1004 sal_Unicode sz[RTL_USTR_MAX_VALUEOFDOUBLE];
1005 return insert( offset, sz, rtl_ustr_valueOfDouble( sz, d ) );
1006 }
1007
1008 /**
1009 Inserts a single UTF-32 character into this string buffer.
1010
1011 <p>The single UTF-32 character will be represented within the string
1012 buffer as either one or two UTF-16 code units.</p>
1013
1014 @param offset the offset into this string buffer (from zero to the length
1015 of this string buffer, inclusive)
1016
1017 @param c a well-formed UTF-32 code unit (that is, a value in the range
1018 <code>0</code>&ndash;<code>0x10FFFF</code>, but excluding
1019 <code>0xD800</code>&ndash;<code>0xDFFF</code>)
1020
1021 @return this string buffer
1022 */
1023 OUStringBuffer & insertUtf32(sal_Int32 offset, sal_uInt32 c) {
1024 rtl_uStringbuffer_insertUtf32(&pData, &nCapacity, offset, c);
1025 return *this;
1026 }
1027
1028 /**
1029 Removes the characters in a substring of this sequence.
1030
1031 The substring begins at the specified <code>start</code> and
1032 is <code>len</code> characters long.
1033
1034 start must be >= 0 && <= This->length
1035
1036 @param start The beginning index, inclusive
1037 @param len The substring length
1038 @return this string buffer.
1039 */
1040 OUStringBuffer & remove( sal_Int32 start, sal_Int32 len )
1041 {
1042 rtl_uStringbuffer_remove( &pData, start, len );
1043 return *this;
1044 }
1045
1046 /**
1047 Removes the tail of a string buffer start at the indicate position
1048
1049 start must be >= 0 && <= This->length
1050
1051 @param start The beginning index, inclusive. default to 0
1052 @return this string buffer.
1053
1054 @since LibreOffice 4.0
1055 */
1056 OUStringBuffer & truncate( sal_Int32 start = 0 )
1057 {
1058 rtl_uStringbuffer_remove( &pData, start, getLength() - start );
1059 return *this;
1060 }
1061
1062 /**
1063 Replace all occurrences of
1064 oldChar in this string buffer with newChar.
1065
1066 @since LibreOffice 4.0
1067
1068 @param oldChar the old character.
1069 @param newChar the new character.
1070 @return this string buffer
1071 */
1072 OUStringBuffer& replace( sal_Unicode oldChar, sal_Unicode newChar )
1073 {
1074 sal_Int32 index = 0;
1075 while((index = indexOf(oldChar, index)) >= 0)
1076 {
1077 pData->buffer[ index ] = newChar;
1078 }
1079 return *this;
1080 }
1081
1082 /** Allows access to the internal data of this OUStringBuffer, for effective
1083 manipulation.
1084
1085 This method should be used with care. After you have called this
1086 method, you may use the returned pInternalData or pInternalCapacity only
1087 as long as you make no other method call on this OUStringBuffer.
1088
1089 @param pInternalData
1090 This output parameter receives a pointer to the internal data
1091 (rtl_uString pointer). pInternalData itself must not be null.
1092
1093 @param pInternalCapacity
1094 This output parameter receives a pointer to the internal capacity.
1095 pInternalCapacity itself must not be null.
1096 */
1097 inline void accessInternals(rtl_uString *** pInternalData,
1098 sal_Int32 ** pInternalCapacity)
1099 {
1100 *pInternalData = &pData;
1101 *pInternalCapacity = &nCapacity;
1102 }
1103
1104
1105 /**
1106 Returns the index within this string of the first occurrence of the
1107 specified character, starting the search at the specified index.
1108
1109 @since LibreOffice 4.0
1110
1111 @param ch character to be located.
1112 @param fromIndex the index to start the search from.
1113 The index must be greater or equal than 0
1114 and less or equal as the string length.
1115 @return the index of the first occurrence of the character in the
1116 character sequence represented by this string that is
1117 greater than or equal to fromIndex, or
1118 -1 if the character does not occur.
1119 */
1120 sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
1121 {
1122 sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
1123 return (ret < 0 ? ret : ret+fromIndex);
1124 }
1125
1126 /**
1127 Returns the index within this string of the last occurrence of the
1128 specified character, searching backward starting at the end.
1129
1130 @since LibreOffice 4.0
1131
1132 @param ch character to be located.
1133 @return the index of the last occurrence of the character in the
1134 character sequence represented by this string, or
1135 -1 if the character does not occur.
1136 */
1137 sal_Int32 lastIndexOf( sal_Unicode ch ) const SAL_THROW(())
1138 {
1139 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
1140 }
1141
1142 /**
1143 Returns the index within this string of the last occurrence of the
1144 specified character, searching backward starting before the specified
1145 index.
1146
1147 @since LibreOffice 4.0
1148
1149 @param ch character to be located.
1150 @param fromIndex the index before which to start the search.
1151 @return the index of the last occurrence of the character in the
1152 character sequence represented by this string that
1153 is less than fromIndex, or -1
1154 if the character does not occur before that point.
1155 */
1156 sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const SAL_THROW(())
1157 {
1158 return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
1159 }
1160
1161 /**
1162 Returns the index within this string of the first occurrence of the
1163 specified substring, starting at the specified index.
1164
1165 If str doesn't include any character, always -1 is
1166 returned. This is also the case, if both strings are empty.
1167
1168 @since LibreOffice 4.0
1169
1170 @param str the substring to search for.
1171 @param fromIndex the index to start the search from.
1172 @return If the string argument occurs one or more times as a substring
1173 within this string at the starting index, then the index
1174 of the first character of the first such substring is
1175 returned. If it does not occur as a substring starting
1176 at fromIndex or beyond, -1 is returned.
1177 */
1178 sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
1179 {
1180 sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
1181 str.pData->buffer, str.pData->length );
1182 return (ret < 0 ? ret : ret+fromIndex);
1183 }
1184
1185 /**
1186 @overload
1187 This function accepts an ASCII string literal as its argument.
1188
1189 @since LibreOffice 4.0
1190 */
1191 template< typename T >
1192 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const SAL_THROW(())
1193 {
1194 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1195 sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
1196 pData->buffer + fromIndex, pData->length - fromIndex, literal,
1197 internal::ConstCharArrayDetector< T, void >::size - 1);
1198 return ret < 0 ? ret : ret + fromIndex;
1199 }
1200
1201 /**
1202 Returns the index within this string of the last occurrence of
1203 the specified substring, searching backward starting at the end.
1204
1205 The returned index indicates the starting index of the substring
1206 in this string.
1207 If str doesn't include any character, always -1 is
1208 returned. This is also the case, if both strings are empty.
1209
1210 @since LibreOffice 4.0
1211
1212 @param str the substring to search for.
1213 @return If the string argument occurs one or more times as a substring
1214 within this string, then the index of the first character of
1215 the last such substring is returned. If it does not occur as
1216 a substring, -1 is returned.
1217 */
1218 sal_Int32 lastIndexOf( const OUString & str ) const SAL_THROW(())
1219 {
1220 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
1221 str.pData->buffer, str.pData->length );
1222 }
1223
1224 /**
1225 Returns the index within this string of the last occurrence of
1226 the specified substring, searching backward starting before the specified
1227 index.
1228
1229 The returned index indicates the starting index of the substring
1230 in this string.
1231 If str doesn't include any character, always -1 is
1232 returned. This is also the case, if both strings are empty.
1233
1234 @since LibreOffice 4.0
1235
1236 @param str the substring to search for.
1237 @param fromIndex the index before which to start the search.
1238 @return If the string argument occurs one or more times as a substring
1239 within this string before the starting index, then the index
1240 of the first character of the last such substring is
1241 returned. Otherwise, -1 is returned.
1242 */
1243 sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const SAL_THROW(())
1244 {
1245 return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
1246 str.pData->buffer, str.pData->length );
1247 }
1248
1249 /**
1250 @overload
1251 This function accepts an ASCII string literal as its argument.
1252 @since LibreOffice 4.0
1253 */
1254 template< typename T >
1255 typename internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const SAL_THROW(())
1256 {
1257 assert( strlen( literal ) == internal::ConstCharArrayDetector< T >::size - 1 );
1258 return rtl_ustr_lastIndexOfAscii_WithLength(
1259 pData->buffer, pData->length, literal, internal::ConstCharArrayDetector< T, void >::size - 1);
1260 }
1261
1262 /**
1263 Strip the given character from the start of the buffer.
1264
1265 @since LibreOffice 4.0
1266
1267 @param c the character to strip
1268 @return The number of characters stripped
1269
1270 */
1271 sal_Int32 stripStart(sal_Unicode c = (sal_Unicode)' ')
1272 {
1273 sal_Int32 index;
1274 for(index = 0; index < getLength() ; index++)
1275 {
1276 if(pData->buffer[ index ] != c)
1277 {
1278 break;
1279 }
1280 }
1281 if(index)
1282 {
1283 remove(0, index);
1284 }
1285 return index;
1286 }
1287
1288 /**
1289 Strip the given character from the end of the buffer.
1290
1291 @since LibreOffice 4.0
1292
1293 @param c the character to strip
1294 @return The number of characters stripped
1295
1296 */
1297 sal_Int32 stripEnd(sal_Unicode c = (sal_Unicode)' ')
1298 {
1299 sal_Int32 result = getLength();
1300 sal_Int32 index;
1301 for(index = getLength(); index > 0 ; index--)
1302 {
1303 if(pData->buffer[ index - 1 ] != c)
1304 {
1305 break;
1306 }
1307 }
1308 if(index < getLength())
1309 {
1310 truncate(index);
1311 }
1312 return result - getLength();
1313 }
1314 /**
1315 Strip the given character from the both end of the buffer.
1316
1317 @since LibreOffice 4.0
1318
1319 @param c the character to strip
1320 @return The number of characters stripped
1321
1322 */
1323 sal_Int32 strip(sal_Unicode c = (sal_Unicode)' ')
1324 {
1325 return stripStart(c) + stripEnd(c);
1326 }
1327 /**
1328 Returns a new string buffer that is a substring of this string.
1329
1330 The substring begins at the specified beginIndex. If
1331 beginIndex is negative or be greater than the length of
1332 this string, behaviour is undefined.
1333
1334 @param beginIndex the beginning index, inclusive.
1335 @return the specified substring.
1336 @since LibreOffice 4.1
1337 */
1338 OUStringBuffer copy( sal_Int32 beginIndex ) const SAL_THROW(())
1339 {
1340 assert(beginIndex >= 0 && beginIndex <= getLength());
1341 return copy( beginIndex, getLength() - beginIndex );
1342 }
1343
1344 /**
1345 Returns a new string buffer that is a substring of this string.
1346
1347 The substring begins at the specified beginIndex and contains count
1348 characters. If either beginIndex or count are negative,
1349 or beginIndex + count are greater than the length of this string
1350 then behaviour is undefined.
1351
1352 @param beginIndex the beginning index, inclusive.
1353 @param count the number of characters.
1354 @return the specified substring.
1355 @since LibreOffice 4.1
1356 */
1357 OUStringBuffer copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(())
1358 {
1359 assert(beginIndex >= 0 && beginIndex <= getLength());
1360 assert(count >= 0 && count <= getLength() - beginIndex);
1361 rtl_uString *pNew = 0;
1362 rtl_uStringbuffer_newFromStr_WithLength( &pNew, getStr() + beginIndex, count );
1363 return OUStringBuffer( pNew, count + 16 );
1364 }
1365
1366#ifdef LIBO_INTERNAL_ONLY
1367 // This is to complement the RTL_FAST_STRING operator+, which allows any combination of valid operands,
1368 // even two buffers. It's intentional it returns OUString, just like the operator+ would in the fast variant.
1369#ifndef RTL_FAST_STRING
1370 /**
1371 @internal
1372 @since LibreOffice 4.1
1373 */
1374 friend OUString operator+( const OUStringBuffer& str1, const OUStringBuffer& str2 ) SAL_THROW(())
1375 {
1376 return OUString( str1.pData ).concat( str2.pData );
1377 }
1378#endif
1379#endif
1380
1381private:
1382 OUStringBuffer( rtl_uString * value, const sal_Int32 capacity )
1383 {
1384 pData = value;
1385 nCapacity = capacity;
1386 }
1387
1388 /**
1389 A pointer to the data structur which contains the data.
1390 */
1391 rtl_uString * pData;
1392
1393 /**
1394 The len of the pData->buffer.
1395 */
1396 sal_Int32 nCapacity;
1397};
1398
1399#ifdef RTL_FAST_STRING
1400/**
1401 @internal
1402*/
1403template<>
1404struct ToStringHelper< OUStringBuffer >
1405 {
1406 static int length( const OUStringBuffer& s ) { return s.getLength(); }
1407 static sal_Unicode* addData( sal_Unicode* buffer, const OUStringBuffer& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); }
1408 static const bool allowOStringConcat = false;
1409 static const bool allowOUStringConcat = true;
1410 };
1411#endif
1412
1413}
1414
1415#ifdef RTL_STRING_UNITTEST
1416namespace rtl
1417{
1418typedef rtlunittest::OUStringBuffer OUStringBuffer;
1419}
1420#endif
1421
1422#ifdef RTL_USING
1423using ::rtl::OUStringBuffer;
1424#endif
1425
1426#endif // INCLUDED_RTL_USTRBUF_HXX
1427
1428/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1429