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 contructor 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>'\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