xref: /trunk/main/sal/inc/rtl/strbuf.hxx (revision a8f4084d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _RTL_STRBUF_HXX_
25 #define _RTL_STRBUF_HXX_
26 
27 #include "osl/diagnose.h"
28 #include <rtl/strbuf.h>
29 #include <rtl/string.hxx>
30 
31 #ifdef __cplusplus
32 
33 namespace rtl
34 {
35 
36 /** @HTML
37 
38     A string buffer implements a mutable sequence of characters.
39     <p>
40     String buffers are safe for use by multiple threads. The methods
41     are synchronized where necessary so that all the operations on any
42     particular instance behave as if they occur in some serial order.
43     <p>
44     String buffers are used by the compiler to implement the binary
45     string concatenation operator <code>+</code>. For example, the code:
46     <p><blockquote><pre>
47         x = "a" + 4 + "c"
48     </pre></blockquote><p>
49     is compiled to the equivalent of:
50     <p><blockquote><pre>
51         x = new OStringBuffer().append("a").append(4).append("c")
52                               .toString()
53     </pre></blockquote><p>
54     The principal operations on a <code>OStringBuffer</code> are the
55     <code>append</code> and <code>insert</code> methods, which are
56     overloaded so as to accept data of any type. Each effectively
57     converts a given datum to a string and then appends or inserts the
58     characters of that string to the string buffer. The
59     <code>append</code> method always adds these characters at the end
60     of the buffer; the <code>insert</code> method adds the characters at
61     a specified point.
62     <p>
63     For example, if <code>z</code> refers to a string buffer object
64     whose current contents are "<code>start</code>", then
65     the method call <code>z.append("le")</code> would cause the string
66     buffer to contain "<code>startle</code>", whereas
67     <code>z.insert(4, "le")</code> would alter the string buffer to
68     contain "<code>starlet</code>".
69     <p>
70     Every string buffer has a capacity. As long as the length of the
71     character sequence contained in the string buffer does not exceed
72     the capacity, it is not necessary to allocate a new internal
73     buffer array. If the internal buffer overflows, it is
74     automatically made larger.
75  */
76 class OStringBuffer
77 {
78 public:
79     /**
80         Constructs a string buffer with no characters in it and an
81         initial capacity of 16 characters.
82      */
OStringBuffer()83     OStringBuffer()
84         : pData(NULL)
85         , nCapacity( 16 )
86     {
87         rtl_string_new_WithLength( &pData, nCapacity );
88     }
89 
90     /**
91         Allocates a new string buffer that contains the same sequence of
92         characters as the string buffer argument.
93 
94         @param   value   a <code>OStringBuffer</code>.
95      */
OStringBuffer(const OStringBuffer & value)96     OStringBuffer( const OStringBuffer & value )
97         : pData(NULL)
98         , nCapacity( value.nCapacity )
99     {
100         rtl_stringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
101     }
102 
103     /**
104         Constructs a string buffer with no characters in it and an
105         initial capacity specified by the <code>length</code> argument.
106 
107         @param      length   the initial capacity.
108      */
OStringBuffer(sal_Int32 length)109     OStringBuffer(sal_Int32 length)
110         : pData(NULL)
111         , nCapacity( length )
112     {
113         rtl_string_new_WithLength( &pData, length );
114     }
115 
116     /**
117         Constructs a string buffer so that it represents the same
118         sequence of characters as the string argument.
119 
120         The initial
121         capacity of the string buffer is <code>16</code> plus the length
122         of the string argument.
123 
124         @param   value   the initial string value.
125      */
OStringBuffer(OString value)126     OStringBuffer(OString value)
127         : pData(NULL)
128         , nCapacity( value.getLength() + 16 )
129     {
130         rtl_stringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
131     }
132 
133     /** Assign to this a copy of value.
134      */
operator =(const OStringBuffer & value)135     OStringBuffer& operator = ( const OStringBuffer& value )
136     {
137         if (this != &value)
138         {
139             rtl_stringbuffer_newFromStringBuffer(&pData,
140                                                   value.nCapacity,
141                                                   value.pData);
142             nCapacity = value.nCapacity;
143         }
144         return *this;
145     }
146 
147     /**
148         Release the string data.
149      */
~OStringBuffer()150     ~OStringBuffer()
151     {
152         rtl_string_release( pData );
153     }
154 
155     /**
156         Fill the string data in the new string and clear the buffer.
157 
158         This method is more efficient than the constructor of the string. It does
159         not copy the buffer.
160 
161         @return the string previously contained in the buffer.
162      */
makeStringAndClear()163     OString makeStringAndClear()
164     {
165         OString aRet( pData );
166         rtl_string_new(&pData);
167         nCapacity = 0;
168         return aRet;
169     }
170 
171     /**
172         Returns the length (character count) of this string buffer.
173 
174         @return  the number of characters in this string buffer.
175      */
getLength() const176     sal_Int32 getLength() const
177     {
178         return pData->length;
179     }
180 
181     /**
182         Returns the current capacity of the String buffer.
183 
184         The capacity
185         is the amount of storage available for newly inserted
186         characters. The real buffer size is 2 bytes longer, because
187         all strings are 0 terminated.
188 
189         @return  the current capacity of this string buffer.
190      */
getCapacity() const191     sal_Int32 getCapacity() const
192     {
193         return nCapacity;
194     }
195 
196     /**
197         Ensures that the capacity of the buffer is at least equal to the
198         specified minimum.
199 
200         The new capacity will be at least as large as the maximum of the current
201         length (so that no contents of the buffer is destroyed) and the given
202         minimumCapacity. If the given minimumCapacity is negative, nothing is
203         changed.
204 
205         @param   minimumCapacity   the minimum desired capacity.
206      */
ensureCapacity(sal_Int32 minimumCapacity)207     void ensureCapacity(sal_Int32 minimumCapacity)
208     {
209         rtl_stringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
210     }
211 
212     /**
213         Sets the length of this String buffer.
214 
215         If the <code>newLength</code> argument is less than the current
216         length of the string buffer, the string buffer is truncated to
217         contain exactly the number of characters given by the
218         <code>newLength</code> argument.
219         <p>
220         If the <code>newLength</code> argument is greater than or equal
221         to the current length, sufficient null characters
222         (<code>'&#92;u0000'</code>) are appended to the string buffer so that
223         length becomes the <code>newLength</code> argument.
224         <p>
225         The <code>newLength</code> argument must be greater than or equal
226         to <code>0</code>.
227 
228         @param      newLength   the new length of the buffer.
229      */
setLength(sal_Int32 newLength)230     void setLength(sal_Int32 newLength)
231     {
232         OSL_ASSERT(newLength >= 0);
233         // Avoid modifications if pData points to const empty string:
234         if( newLength != pData->length )
235         {
236             if( newLength > nCapacity )
237                 rtl_stringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
238             else
239                 pData->buffer[newLength] = '\0';
240             pData->length = newLength;
241         }
242     }
243 
244     /**
245         Returns the character at a specific index in this string buffer.
246 
247         The first character of a string buffer is at index
248         <code>0</code>, the next at index <code>1</code>, and so on, for
249         array indexing.
250         <p>
251         The index argument must be greater than or equal to
252         <code>0</code>, and less than the length of this string buffer.
253 
254         @param      index   the index of the desired character.
255         @return     the character at the specified index of this string buffer.
256      */
charAt(sal_Int32 index)257     sal_Char charAt( sal_Int32 index )
258     {
259         OSL_ASSERT(index >= 0 && index < pData->length);
260         return pData->buffer[ index ];
261     }
262 
263     /**
264         Return a null terminated character array.
265      */
266     operator        const sal_Char *() const { return pData->buffer; }
267 
268     /**
269         Return a null terminated character array.
270      */
getStr() const271     const sal_Char* getStr() const { return pData->buffer; }
272 
273 
274     /**
275         The character at the specified index of this string buffer is set
276         to <code>ch</code>.
277 
278         The index argument must be greater than or equal to
279         <code>0</code>, and less than the length of this string buffer.
280 
281         @param      index   the index of the character to modify.
282         @param      ch      the new character.
283      */
setCharAt(sal_Int32 index,sal_Char ch)284     OStringBuffer & setCharAt(sal_Int32 index, sal_Char ch)
285     {
286         OSL_ASSERT(index >= 0 && index < pData->length);
287         pData->buffer[ index ] = ch;
288         return *this;
289     }
290 
291     /**
292         Appends the string to this string buffer.
293 
294         The characters of the <code>String</code> argument are appended, in
295         order, to the contents of this string buffer, increasing the
296         length of this string buffer by the length of the argument.
297 
298         @param   str   a string.
299         @return  this string buffer.
300      */
append(const OString & str)301     OStringBuffer & append(const OString &str)
302     {
303         return append( str.getStr(), str.getLength() );
304     }
305 
306     /**
307         Appends the string representation of the <code>char</code> array
308         argument to this string buffer.
309 
310         The characters of the array argument are appended, in order, to
311         the contents of this string buffer. The length of this string
312         buffer increases by the length of the argument.
313 
314         @param   str   the characters to be appended.
315         @return  this string buffer.
316      */
append(const sal_Char * str)317     OStringBuffer & append( const sal_Char * str )
318     {
319         return append( str, rtl_str_getLength( str ) );
320     }
321 
322     /**
323         Appends the string representation of the <code>char</code> array
324         argument to this string buffer.
325 
326         Characters of the character array <code>str</code> are appended,
327         in order, to the contents of this string buffer. The length of this
328         string buffer increases by the value of <code>len</code>.
329 
330         @param str the characters to be appended; must be non-null, and must
331         point to at least len characters
332         @param len the number of characters to append; must be non-negative
333         @return  this string buffer.
334      */
append(const sal_Char * str,sal_Int32 len)335     OStringBuffer & append( const sal_Char * str, sal_Int32 len)
336     {
337         // insert behind the last character
338         rtl_stringbuffer_insert( &pData, &nCapacity, getLength(), str, len );
339         return *this;
340     }
341 
342     /**
343         Appends the string representation of the <code>sal_Bool</code>
344         argument to the string buffer.
345 
346         The argument is converted to a string as if by the method
347         <code>String.valueOf</code>, and the characters of that
348         string are then appended to this string buffer.
349 
350         @param   b   a <code>sal_Bool</code>.
351         @return  this string buffer.
352      */
append(sal_Bool b)353     OStringBuffer & append(sal_Bool b)
354     {
355         sal_Char sz[RTL_STR_MAX_VALUEOFBOOLEAN];
356         return append( sz, rtl_str_valueOfBoolean( sz, b ) );
357     }
358 
359     /**
360         Appends the string representation of the <code>char</code>
361         argument to this string buffer.
362 
363         The argument is appended to the contents of this string buffer.
364         The length of this string buffer increases by <code>1</code>.
365 
366         @param   ch   a <code>char</code>.
367         @return  this string buffer.
368      */
append(sal_Char c)369     OStringBuffer & append(sal_Char c)
370     {
371         return append( &c, 1 );
372     }
373 
374     /**
375         Appends the string representation of the <code>sal_Int32</code>
376         argument to this string buffer.
377 
378         The argument is converted to a string as if by the method
379         <code>String.valueOf</code>, and the characters of that
380         string are then appended to this string buffer.
381 
382         @param   i   an <code>sal_Int32</code>.
383         @return  this string buffer.
384      */
append(sal_Int32 i,sal_Int16 radix=10)385     OStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
386     {
387         sal_Char sz[RTL_STR_MAX_VALUEOFINT32];
388         return append( sz, rtl_str_valueOfInt32( sz, i, radix ) );
389     }
390 
391     /**
392         Appends the string representation of the <code>long</code>
393         argument to this string buffer.
394 
395         The argument is converted to a string as if by the method
396         <code>String.valueOf</code>, and the characters of that
397         string are then appended to this string buffer.
398 
399         @param   l   a <code>long</code>.
400         @return  this string buffer.
401      */
append(sal_Int64 l,sal_Int16 radix=10)402     OStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
403     {
404         sal_Char sz[RTL_STR_MAX_VALUEOFINT64];
405         return append( sz, rtl_str_valueOfInt64( sz, l, radix ) );
406     }
407 
408     /**
409         Appends the string representation of the <code>float</code>
410         argument to this string buffer.
411 
412         The argument is converted to a string as if by the method
413         <code>String.valueOf</code>, and the characters of that
414         string are then appended to this string buffer.
415 
416         @param   f   a <code>float</code>.
417         @return  this string buffer.
418      */
append(float f)419     OStringBuffer & append(float f)
420     {
421         sal_Char sz[RTL_STR_MAX_VALUEOFFLOAT];
422         return append( sz, rtl_str_valueOfFloat( sz, f ) );
423     }
424 
425     /**
426         Appends the string representation of the <code>double</code>
427         argument to this string buffer.
428 
429         The argument is converted to a string as if by the method
430         <code>String.valueOf</code>, and the characters of that
431         string are then appended to this string buffer.
432 
433         @param   d   a <code>double</code>.
434         @return  this string buffer.
435      */
append(double d)436     OStringBuffer & append(double d)
437     {
438         sal_Char sz[RTL_STR_MAX_VALUEOFDOUBLE];
439         return append( sz, rtl_str_valueOfDouble( sz, d ) );
440     }
441 
442     /**
443         Inserts the string into this string buffer.
444 
445         The characters of the <code>String</code> argument are inserted, in
446         order, into this string buffer at the indicated offset. The length
447         of this string buffer is increased by the length of the argument.
448         <p>
449         The offset argument must be greater than or equal to
450         <code>0</code>, and less than or equal to the length of this
451         string buffer.
452 
453         @param      offset   the offset.
454         @param      str      a string.
455         @return     this string buffer.
456      */
insert(sal_Int32 offset,const OString & str)457     OStringBuffer & insert(sal_Int32 offset, const OString & str)
458     {
459         return insert( offset, str.getStr(), str.getLength() );
460     }
461 
462     /**
463         Inserts the string representation of the <code>char</code> array
464         argument into this string buffer.
465 
466         The characters of the array argument are inserted into the
467         contents of this string buffer at the position indicated by
468         <code>offset</code>. The length of this string buffer increases by
469         the length of the argument.
470         <p>
471         The offset argument must be greater than or equal to
472         <code>0</code>, and less than or equal to the length of this
473         string buffer.
474 
475         @param      offset   the offset.
476         @param      ch       a character array.
477         @return     this string buffer.
478      */
insert(sal_Int32 offset,const sal_Char * str)479     OStringBuffer & insert( sal_Int32 offset, const sal_Char * str )
480     {
481         return insert( offset, str, rtl_str_getLength( str ) );
482     }
483 
484     /**
485         Inserts the string representation of the <code>char</code> array
486         argument into this string buffer.
487 
488         The characters of the array argument are inserted into the
489         contents of this string buffer at the position indicated by
490         <code>offset</code>. The length of this string buffer increases by
491         the length of the argument.
492         <p>
493         The offset argument must be greater than or equal to
494         <code>0</code>, and less than or equal to the length of this
495         string buffer.
496 
497         @param      offset   the offset.
498         @param      ch       a character array.
499         @param       len     the number of characters to append.
500         @return     this string buffer.
501      */
insert(sal_Int32 offset,const sal_Char * str,sal_Int32 len)502     OStringBuffer & insert( sal_Int32 offset, const sal_Char * str, sal_Int32 len)
503     {
504         // insert behind the last character
505         rtl_stringbuffer_insert( &pData, &nCapacity, offset, str, len );
506         return *this;
507     }
508 
509     /**
510         Inserts the string representation of the <code>sal_Bool</code>
511         argument into this string buffer.
512 
513         The second argument is converted to a string as if by the method
514         <code>String.valueOf</code>, and the characters of that
515         string are then inserted into this string buffer at the indicated
516         offset.
517         <p>
518         The offset argument must be greater than or equal to
519         <code>0</code>, and less than or equal to the length of this
520         string buffer.
521 
522         @param      offset   the offset.
523         @param      b        a <code>sal_Bool</code>.
524         @return     this string buffer.
525      */
insert(sal_Int32 offset,sal_Bool b)526     OStringBuffer & insert(sal_Int32 offset, sal_Bool b)
527     {
528         sal_Char sz[RTL_STR_MAX_VALUEOFBOOLEAN];
529         return insert( offset, sz, rtl_str_valueOfBoolean( sz, b ) );
530     }
531 
532     /**
533         Inserts the string representation of the <code>char</code>
534         argument into this string buffer.
535 
536         The second argument is inserted into the contents of this string
537         buffer at the position indicated by <code>offset</code>. The length
538         of this string buffer increases by one.
539         <p>
540         The offset argument must be greater than or equal to
541         <code>0</code>, and less than or equal to the length of this
542         string buffer.
543 
544         @param      offset   the offset.
545         @param      ch       a <code>char</code>.
546         @return     this string buffer.
547      */
insert(sal_Int32 offset,sal_Char c)548     OStringBuffer & insert(sal_Int32 offset, sal_Char c)
549     {
550         return insert( offset, &c, 1 );
551     }
552 
553     /**
554         Inserts the string representation of the second <code>sal_Int32</code>
555         argument into this string buffer.
556 
557         The second argument is converted to a string as if by the method
558         <code>String.valueOf</code>, and the characters of that
559         string are then inserted into this string buffer at the indicated
560         offset.
561         <p>
562         The offset argument must be greater than or equal to
563         <code>0</code>, and less than or equal to the length of this
564         string buffer.
565 
566         @param      offset   the offset.
567         @param      b        an <code>sal_Int32</code>.
568         @return     this string buffer.
569      */
insert(sal_Int32 offset,sal_Int32 i,sal_Int16 radix=10)570     OStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
571     {
572         sal_Char sz[RTL_STR_MAX_VALUEOFINT32];
573         return insert( offset, sz, rtl_str_valueOfInt32( sz, i, radix ) );
574     }
575 
576     /**
577         Inserts the string representation of the <code>long</code>
578         argument into this string buffer.
579 
580         The second argument is converted to a string as if by the method
581         <code>String.valueOf</code>, and the characters of that
582         string are then inserted into this string buffer at the indicated
583         offset.
584         <p>
585         The offset argument must be greater than or equal to
586         <code>0</code>, and less than or equal to the length of this
587         string buffer.
588 
589         @param      offset   the offset.
590         @param      b        a <code>long</code>.
591         @return     this string buffer.
592      */
insert(sal_Int32 offset,sal_Int64 l,sal_Int16 radix=10)593     OStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
594     {
595         sal_Char sz[RTL_STR_MAX_VALUEOFINT64];
596         return insert( offset, sz, rtl_str_valueOfInt64( sz, l, radix ) );
597     }
598 
599     /**
600         Inserts the string representation of the <code>float</code>
601         argument into this string buffer.
602 
603         The second 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 inserted into this string buffer at the indicated
606         offset.
607         <p>
608         The offset argument must be greater than or equal to
609         <code>0</code>, and less than or equal to the length of this
610         string buffer.
611 
612         @param      offset   the offset.
613         @param      b        a <code>float</code>.
614         @return     this string buffer.
615      */
insert(sal_Int32 offset,float f)616     OStringBuffer insert(sal_Int32 offset, float f)
617     {
618         sal_Char sz[RTL_STR_MAX_VALUEOFFLOAT];
619         return insert( offset, sz, rtl_str_valueOfFloat( sz, f ) );
620     }
621 
622     /**
623         Inserts the string representation of the <code>double</code>
624         argument into this string buffer.
625 
626         The second argument is converted to a string as if by the method
627         <code>String.valueOf</code>, and the characters of that
628         string are then inserted into this string buffer at the indicated
629         offset.
630         <p>
631         The offset argument must be greater than or equal to
632         <code>0</code>, and less than or equal to the length of this
633         string buffer.
634 
635         @param      offset   the offset.
636         @param      b        a <code>double</code>.
637         @return     this string buffer.
638      */
insert(sal_Int32 offset,double d)639     OStringBuffer & insert(sal_Int32 offset, double d)
640     {
641         sal_Char sz[RTL_STR_MAX_VALUEOFDOUBLE];
642         return insert( offset, sz, rtl_str_valueOfDouble( sz, d ) );
643     }
644 private:
645     /**
646         A pointer to the data structur which contains the data.
647      */
648     rtl_String * pData;
649 
650     /**
651         The len of the pData->buffer.
652      */
653     sal_Int32       nCapacity;
654 };
655 
656 }
657 
658 #endif  /* __cplusplus */
659 #endif  /* _RTL_STRBUF_HXX_ */
660 
661 
662