001 /* StringBuffer.java -- Growable strings 002 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 003 Free Software Foundation, Inc. 004 005 This file is part of GNU Classpath. 006 007 GNU Classpath is free software; you can redistribute it and/or modify 008 it under the terms of the GNU General Public License as published by 009 the Free Software Foundation; either version 2, or (at your option) 010 any later version. 011 012 GNU Classpath is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of 014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 General Public License for more details. 016 017 You should have received a copy of the GNU General Public License 018 along with GNU Classpath; see the file COPYING. If not, write to the 019 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 020 02110-1301 USA. 021 022 Linking this library statically or dynamically with other modules is 023 making a combined work based on this library. Thus, the terms and 024 conditions of the GNU General Public License cover the whole 025 combination. 026 027 As a special exception, the copyright holders of this library give you 028 permission to link this library with independent modules to produce an 029 executable, regardless of the license terms of these independent 030 modules, and to copy and distribute the resulting executable under 031 terms of your choice, provided that you also meet, for each linked 032 independent module, the terms and conditions of the license of that 033 module. An independent module is a module which is not derived from 034 or based on this library. If you modify this library, you may extend 035 this exception to your version of the library, but you are not 036 obligated to do so. If you do not wish to do so, delete this 037 exception statement from your version. */ 038 039 package java.lang; 040 041 import java.io.Serializable; 042 043 /** 044 * <code>StringBuffer</code> represents a changeable <code>String</code>. 045 * It provides the operations required to modify the 046 * <code>StringBuffer</code>, including insert, replace, delete, append, 047 * and reverse. It is thread-safe; meaning that all modifications to a buffer 048 * are in synchronized methods. 049 * 050 * <p><code>StringBuffer</code>s are variable-length in nature, so even if 051 * you initialize them to a certain size, they can still grow larger than 052 * that. <em>Capacity</em> indicates the number of characters the 053 * <code>StringBuffer</code> can have in it before it has to grow (growing 054 * the char array is an expensive operation involving <code>new</code>). 055 * 056 * <p>Incidentally, compilers often implement the String operator "+" 057 * by using a <code>StringBuffer</code> operation:<br> 058 * <code>a + b</code><br> 059 * is the same as<br> 060 * <code>new StringBuffer().append(a).append(b).toString()</code>. 061 * 062 * <p>Classpath's StringBuffer is capable of sharing memory with Strings for 063 * efficiency. This will help when a StringBuffer is converted to a String 064 * and the StringBuffer is not changed after that (quite common when performing 065 * string concatenation). 066 * 067 * @author Paul Fisher 068 * @author John Keiser 069 * @author Tom Tromey 070 * @author Eric Blake (ebb9@email.byu.edu) 071 * @see String 072 * @since 1.0 073 * @status updated to 1.4 074 */ 075 public final class StringBuffer 076 implements Serializable, CharSequence, Appendable 077 { 078 // Implementation note: if you change this class, you usually will 079 // want to change StringBuilder as well. 080 081 /** 082 * Compatible with JDK 1.0+. 083 */ 084 private static final long serialVersionUID = 3388685877147921107L; 085 086 /** 087 * Index of next available character (and thus the size of the current 088 * string contents). Note that this has permissions set this way so that 089 * String can get the value. 090 * 091 * @serial the number of characters in the buffer 092 */ 093 int count; 094 095 /** 096 * The buffer. Note that this has permissions set this way so that String 097 * can get the value. 098 * 099 * @serial the buffer 100 */ 101 char[] value; 102 103 /** 104 * True if the buffer is shared with another object (StringBuffer or 105 * String); this means the buffer must be copied before writing to it again. 106 * Note that this has permissions set this way so that String can get the 107 * value. 108 * 109 * @serial whether the buffer is shared 110 */ 111 boolean shared; 112 113 /** 114 * The default capacity of a buffer. 115 */ 116 private static final int DEFAULT_CAPACITY = 16; 117 118 /** 119 * Create a new StringBuffer with default capacity 16. 120 */ 121 public StringBuffer() 122 { 123 this(DEFAULT_CAPACITY); 124 } 125 126 /** 127 * Create an empty <code>StringBuffer</code> with the specified initial 128 * capacity. 129 * 130 * @param capacity the initial capacity 131 * @throws NegativeArraySizeException if capacity is negative 132 */ 133 public StringBuffer(int capacity) 134 { 135 value = new char[capacity]; 136 } 137 138 /** 139 * Create a new <code>StringBuffer</code> with the characters in the 140 * specified <code>String</code>. Initial capacity will be the size of the 141 * String plus 16. 142 * 143 * @param str the <code>String</code> to convert 144 * @throws NullPointerException if str is null 145 */ 146 public StringBuffer(String str) 147 { 148 // Unfortunately, because the size is 16 larger, we cannot share. 149 count = str.count; 150 value = new char[count + DEFAULT_CAPACITY]; 151 str.getChars(0, count, value, 0); 152 } 153 154 /** 155 * Create a new <code>StringBuffer</code> with the characters from the 156 * specified <code>CharSequence</code>. Initial capacity will be the 157 * size of the CharSequence plus 16. 158 * 159 * @param seq the <code>String</code> to convert 160 * @throws NullPointerException if str is null 161 * @since 1.5 162 */ 163 public StringBuffer(CharSequence seq) 164 { 165 count = Math.max(0, seq.length()); 166 value = new char[count + DEFAULT_CAPACITY]; 167 for (int i = 0; i < count; ++i) 168 value[i] = seq.charAt(i); 169 } 170 171 /** 172 * Get the length of the <code>String</code> this <code>StringBuffer</code> 173 * would create. Not to be confused with the <em>capacity</em> of the 174 * <code>StringBuffer</code>. 175 * 176 * @return the length of this <code>StringBuffer</code> 177 * @see #capacity() 178 * @see #setLength(int) 179 */ 180 public synchronized int length() 181 { 182 return count; 183 } 184 185 /** 186 * Get the total number of characters this <code>StringBuffer</code> can 187 * support before it must be grown. Not to be confused with <em>length</em>. 188 * 189 * @return the capacity of this <code>StringBuffer</code> 190 * @see #length() 191 * @see #ensureCapacity(int) 192 */ 193 public synchronized int capacity() 194 { 195 return value.length; 196 } 197 198 /** 199 * Increase the capacity of this <code>StringBuffer</code>. This will 200 * ensure that an expensive growing operation will not occur until 201 * <code>minimumCapacity</code> is reached. The buffer is grown to the 202 * larger of <code>minimumCapacity</code> and 203 * <code>capacity() * 2 + 2</code>, if it is not already large enough. 204 * 205 * @param minimumCapacity the new capacity 206 * @see #capacity() 207 */ 208 public synchronized void ensureCapacity(int minimumCapacity) 209 { 210 ensureCapacity_unsynchronized(minimumCapacity); 211 } 212 213 /** 214 * Set the length of this StringBuffer. If the new length is greater than 215 * the current length, all the new characters are set to '\0'. If the new 216 * length is less than the current length, the first <code>newLength</code> 217 * characters of the old array will be preserved, and the remaining 218 * characters are truncated. 219 * 220 * @param newLength the new length 221 * @throws IndexOutOfBoundsException if the new length is negative 222 * (while unspecified, this is a StringIndexOutOfBoundsException) 223 * @see #length() 224 */ 225 public synchronized void setLength(int newLength) 226 { 227 if (newLength < 0) 228 throw new StringIndexOutOfBoundsException(newLength); 229 230 int valueLength = value.length; 231 232 /* Always call ensureCapacity_unsynchronized in order to preserve 233 copy-on-write semantics. */ 234 ensureCapacity_unsynchronized(newLength); 235 236 if (newLength < valueLength) 237 { 238 /* If the StringBuffer's value just grew, then we know that 239 value is newly allocated and the region between count and 240 newLength is filled with '\0'. */ 241 count = newLength; 242 } 243 else 244 { 245 /* The StringBuffer's value doesn't need to grow. However, 246 we should clear out any cruft that may exist. */ 247 while (count < newLength) 248 value[count++] = '\0'; 249 } 250 } 251 252 /** 253 * Get the character at the specified index. 254 * 255 * @param index the index of the character to get, starting at 0 256 * @return the character at the specified index 257 * @throws IndexOutOfBoundsException if index is negative or >= length() 258 */ 259 public synchronized char charAt(int index) 260 { 261 if (index < 0 || index >= count) 262 throw new StringIndexOutOfBoundsException(index); 263 return value[index]; 264 } 265 266 /** 267 * Get the code point at the specified index. This is like #charAt(int), 268 * but if the character is the start of a surrogate pair, and the 269 * following character completes the pair, then the corresponding 270 * supplementary code point is returned. 271 * @param index the index of the codepoint to get, starting at 0 272 * @return the codepoint at the specified index 273 * @throws IndexOutOfBoundsException if index is negative or >= length() 274 * @since 1.5 275 */ 276 public synchronized int codePointAt(int index) 277 { 278 return Character.codePointAt(value, index, count); 279 } 280 281 /** 282 * Get the code point before the specified index. This is like 283 * #codePointAt(int), but checks the characters at <code>index-1</code> and 284 * <code>index-2</code> to see if they form a supplementary code point. 285 * @param index the index just past the codepoint to get, starting at 0 286 * @return the codepoint at the specified index 287 * @throws IndexOutOfBoundsException if index is negative or >= length() 288 * @since 1.5 289 */ 290 public synchronized int codePointBefore(int index) 291 { 292 // Character.codePointBefore() doesn't perform this check. We 293 // could use the CharSequence overload, but this is just as easy. 294 if (index >= count) 295 throw new IndexOutOfBoundsException(); 296 return Character.codePointBefore(value, index, 1); 297 } 298 299 /** 300 * Get the specified array of characters. <code>srcOffset - srcEnd</code> 301 * characters will be copied into the array you pass in. 302 * 303 * @param srcOffset the index to start copying from (inclusive) 304 * @param srcEnd the index to stop copying from (exclusive) 305 * @param dst the array to copy into 306 * @param dstOffset the index to start copying into 307 * @throws NullPointerException if dst is null 308 * @throws IndexOutOfBoundsException if any source or target indices are 309 * out of range (while unspecified, source problems cause a 310 * StringIndexOutOfBoundsException, and dest problems cause an 311 * ArrayIndexOutOfBoundsException) 312 * @see System#arraycopy(Object, int, Object, int, int) 313 */ 314 public synchronized void getChars(int srcOffset, int srcEnd, 315 char[] dst, int dstOffset) 316 { 317 if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset) 318 throw new StringIndexOutOfBoundsException(); 319 System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); 320 } 321 322 /** 323 * Set the character at the specified index. 324 * 325 * @param index the index of the character to set starting at 0 326 * @param ch the value to set that character to 327 * @throws IndexOutOfBoundsException if index is negative or >= length() 328 * (while unspecified, this is a StringIndexOutOfBoundsException) 329 */ 330 public synchronized void setCharAt(int index, char ch) 331 { 332 if (index < 0 || index >= count) 333 throw new StringIndexOutOfBoundsException(index); 334 // Call ensureCapacity to enforce copy-on-write. 335 ensureCapacity_unsynchronized(count); 336 value[index] = ch; 337 } 338 339 /** 340 * Append the <code>String</code> value of the argument to this 341 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 342 * to <code>String</code>. 343 * 344 * @param obj the <code>Object</code> to convert and append 345 * @return this <code>StringBuffer</code> 346 * @see String#valueOf(Object) 347 * @see #append(String) 348 */ 349 public StringBuffer append(Object obj) 350 { 351 return append(obj == null ? "null" : obj.toString()); 352 } 353 354 /** 355 * Append the <code>String</code> to this <code>StringBuffer</code>. If 356 * str is null, the String "null" is appended. 357 * 358 * @param str the <code>String</code> to append 359 * @return this <code>StringBuffer</code> 360 */ 361 public synchronized StringBuffer append(String str) 362 { 363 if (str == null) 364 str = "null"; 365 int len = str.count; 366 ensureCapacity_unsynchronized(count + len); 367 str.getChars(0, len, value, count); 368 count += len; 369 return this; 370 } 371 372 /** 373 * Append the <code>StringBuffer</code> value of the argument to this 374 * <code>StringBuffer</code>. This behaves the same as 375 * <code>append((Object) stringBuffer)</code>, except it is more efficient. 376 * 377 * @param stringBuffer the <code>StringBuffer</code> to convert and append 378 * @return this <code>StringBuffer</code> 379 * @see #append(Object) 380 * @since 1.4 381 */ 382 public synchronized StringBuffer append(StringBuffer stringBuffer) 383 { 384 if (stringBuffer == null) 385 return append("null"); 386 synchronized (stringBuffer) 387 { 388 int len = stringBuffer.count; 389 ensureCapacity_unsynchronized(count + len); 390 System.arraycopy(stringBuffer.value, 0, value, count, len); 391 count += len; 392 } 393 return this; 394 } 395 396 /** 397 * Append the <code>char</code> array to this <code>StringBuffer</code>. 398 * This is similar (but more efficient) than 399 * <code>append(new String(data))</code>, except in the case of null. 400 * 401 * @param data the <code>char[]</code> to append 402 * @return this <code>StringBuffer</code> 403 * @throws NullPointerException if <code>str</code> is <code>null</code> 404 * @see #append(char[], int, int) 405 */ 406 public StringBuffer append(char[] data) 407 { 408 return append(data, 0, data.length); 409 } 410 411 /** 412 * Append part of the <code>char</code> array to this 413 * <code>StringBuffer</code>. This is similar (but more efficient) than 414 * <code>append(new String(data, offset, count))</code>, except in the case 415 * of null. 416 * 417 * @param data the <code>char[]</code> to append 418 * @param offset the start location in <code>str</code> 419 * @param count the number of characters to get from <code>str</code> 420 * @return this <code>StringBuffer</code> 421 * @throws NullPointerException if <code>str</code> is <code>null</code> 422 * @throws IndexOutOfBoundsException if offset or count is out of range 423 * (while unspecified, this is a StringIndexOutOfBoundsException) 424 */ 425 public synchronized StringBuffer append(char[] data, int offset, int count) 426 { 427 if (offset < 0 || count < 0 || offset > data.length - count) 428 throw new StringIndexOutOfBoundsException(); 429 ensureCapacity_unsynchronized(this.count + count); 430 System.arraycopy(data, offset, value, this.count, count); 431 this.count += count; 432 return this; 433 } 434 435 /** 436 * Append the code point to this <code>StringBuffer</code>. 437 * This is like #append(char), but will append two characters 438 * if a supplementary code point is given. 439 * 440 * @param code the code point to append 441 * @return this <code>StringBuffer</code> 442 * @see Character#toChars(int, char[], int) 443 * @since 1.5 444 */ 445 public synchronized StringBuffer appendCodePoint(int code) 446 { 447 int len = Character.charCount(code); 448 ensureCapacity_unsynchronized(count + len); 449 Character.toChars(code, value, count); 450 count += len; 451 return this; 452 } 453 454 /** 455 * Append the <code>String</code> value of the argument to this 456 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 457 * to <code>String</code>. 458 * 459 * @param bool the <code>boolean</code> to convert and append 460 * @return this <code>StringBuffer</code> 461 * @see String#valueOf(boolean) 462 */ 463 public StringBuffer append(boolean bool) 464 { 465 return append(bool ? "true" : "false"); 466 } 467 468 /** 469 * Append the <code>char</code> to this <code>StringBuffer</code>. 470 * 471 * @param ch the <code>char</code> to append 472 * @return this <code>StringBuffer</code> 473 */ 474 public synchronized StringBuffer append(char ch) 475 { 476 ensureCapacity_unsynchronized(count + 1); 477 value[count++] = ch; 478 return this; 479 } 480 481 /** 482 * Append the <code>CharSequence</code> value of the argument to this 483 * <code>StringBuffer</code>. 484 * 485 * @param seq the <code>CharSequence</code> to append 486 * @return this <code>StringBuffer</code> 487 * @see #append(Object) 488 * @since 1.5 489 */ 490 public synchronized StringBuffer append(CharSequence seq) 491 { 492 if (seq == null) 493 seq = "null"; 494 return append(seq, 0, seq.length()); 495 } 496 497 /** 498 * Append the specified subsequence of the <code>CharSequence</code> 499 * argument to this <code>StringBuffer</code>. 500 * 501 * @param seq the <code>CharSequence</code> to append 502 * @param start the starting index 503 * @param end one past the ending index 504 * @return this <code>StringBuffer</code> 505 * @see #append(Object) 506 * @since 1.5 507 */ 508 public synchronized StringBuffer append(CharSequence seq, int start, int end) 509 { 510 if (seq == null) 511 seq = "null"; 512 if (start < 0 || end < 0 || start > end || end > seq.length()) 513 throw new IndexOutOfBoundsException(); 514 ensureCapacity_unsynchronized(this.count + end - start); 515 for (int i = start; i < end; ++i) 516 value[count++] = seq.charAt(i); 517 return this; 518 } 519 520 /** 521 * Append the <code>String</code> value of the argument to this 522 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 523 * to <code>String</code>. 524 * 525 * @param inum the <code>int</code> to convert and append 526 * @return this <code>StringBuffer</code> 527 * @see String#valueOf(int) 528 */ 529 // GCJ LOCAL: this is native for efficiency. 530 public native StringBuffer append (int inum); 531 532 /** 533 * Append the <code>String</code> value of the argument to this 534 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 535 * to <code>String</code>. 536 * 537 * @param lnum the <code>long</code> to convert and append 538 * @return this <code>StringBuffer</code> 539 * @see String#valueOf(long) 540 */ 541 public StringBuffer append(long lnum) 542 { 543 return append(Long.toString(lnum, 10)); 544 } 545 546 /** 547 * Append the <code>String</code> value of the argument to this 548 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 549 * to <code>String</code>. 550 * 551 * @param fnum the <code>float</code> to convert and append 552 * @return this <code>StringBuffer</code> 553 * @see String#valueOf(float) 554 */ 555 public StringBuffer append(float fnum) 556 { 557 return append(Float.toString(fnum)); 558 } 559 560 /** 561 * Append the <code>String</code> value of the argument to this 562 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 563 * to <code>String</code>. 564 * 565 * @param dnum the <code>double</code> to convert and append 566 * @return this <code>StringBuffer</code> 567 * @see String#valueOf(double) 568 */ 569 public StringBuffer append(double dnum) 570 { 571 return append(Double.toString(dnum)); 572 } 573 574 /** 575 * Delete characters from this <code>StringBuffer</code>. 576 * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is 577 * harmless for end to be larger than length(). 578 * 579 * @param start the first character to delete 580 * @param end the index after the last character to delete 581 * @return this <code>StringBuffer</code> 582 * @throws StringIndexOutOfBoundsException if start or end are out of bounds 583 * @since 1.2 584 */ 585 public synchronized StringBuffer delete(int start, int end) 586 { 587 if (start < 0 || start > count || start > end) 588 throw new StringIndexOutOfBoundsException(start); 589 if (end > count) 590 end = count; 591 // This will unshare if required. 592 ensureCapacity_unsynchronized(count); 593 if (count - end != 0) 594 System.arraycopy(value, end, value, start, count - end); 595 count -= end - start; 596 return this; 597 } 598 599 /** 600 * Delete a character from this <code>StringBuffer</code>. 601 * 602 * @param index the index of the character to delete 603 * @return this <code>StringBuffer</code> 604 * @throws StringIndexOutOfBoundsException if index is out of bounds 605 * @since 1.2 606 */ 607 public StringBuffer deleteCharAt(int index) 608 { 609 return delete(index, index + 1); 610 } 611 612 /** 613 * Replace characters between index <code>start</code> (inclusive) and 614 * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code> 615 * is larger than the size of this StringBuffer, all characters after 616 * <code>start</code> are replaced. 617 * 618 * @param start the beginning index of characters to delete (inclusive) 619 * @param end the ending index of characters to delete (exclusive) 620 * @param str the new <code>String</code> to insert 621 * @return this <code>StringBuffer</code> 622 * @throws StringIndexOutOfBoundsException if start or end are out of bounds 623 * @throws NullPointerException if str is null 624 * @since 1.2 625 */ 626 public synchronized StringBuffer replace(int start, int end, String str) 627 { 628 if (start < 0 || start > count || start > end) 629 throw new StringIndexOutOfBoundsException(start); 630 631 int len = str.count; 632 // Calculate the difference in 'count' after the replace. 633 int delta = len - (end > count ? count : end) + start; 634 ensureCapacity_unsynchronized(count + delta); 635 636 if (delta != 0 && end < count) 637 System.arraycopy(value, end, value, end + delta, count - end); 638 639 str.getChars(0, len, value, start); 640 count += delta; 641 return this; 642 } 643 644 /** 645 * Creates a substring of this StringBuffer, starting at a specified index 646 * and ending at the end of this StringBuffer. 647 * 648 * @param beginIndex index to start substring (base 0) 649 * @return new String which is a substring of this StringBuffer 650 * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds 651 * @see #substring(int, int) 652 * @since 1.2 653 */ 654 public String substring(int beginIndex) 655 { 656 return substring(beginIndex, count); 657 } 658 659 /** 660 * Creates a substring of this StringBuffer, starting at a specified index 661 * and ending at one character before a specified index. This is implemented 662 * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy 663 * the CharSequence interface. 664 * 665 * @param beginIndex index to start at (inclusive, base 0) 666 * @param endIndex index to end at (exclusive) 667 * @return new String which is a substring of this StringBuffer 668 * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of 669 * bounds 670 * @see #substring(int, int) 671 * @since 1.4 672 */ 673 public CharSequence subSequence(int beginIndex, int endIndex) 674 { 675 return substring(beginIndex, endIndex); 676 } 677 678 /** 679 * Creates a substring of this StringBuffer, starting at a specified index 680 * and ending at one character before a specified index. 681 * 682 * @param beginIndex index to start at (inclusive, base 0) 683 * @param endIndex index to end at (exclusive) 684 * @return new String which is a substring of this StringBuffer 685 * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out 686 * of bounds 687 * @since 1.2 688 */ 689 public synchronized String substring(int beginIndex, int endIndex) 690 { 691 int len = endIndex - beginIndex; 692 if (beginIndex < 0 || endIndex > count || endIndex < beginIndex) 693 throw new StringIndexOutOfBoundsException(); 694 if (len == 0) 695 return ""; 696 // Don't copy unless substring is smaller than 1/4 of the buffer. 697 boolean share_buffer = ((len << 2) >= value.length); 698 if (share_buffer) 699 this.shared = true; 700 // Package constructor avoids an array copy. 701 return new String(value, beginIndex, len, share_buffer); 702 } 703 704 /** 705 * Insert a subarray of the <code>char[]</code> argument into this 706 * <code>StringBuffer</code>. 707 * 708 * @param offset the place to insert in this buffer 709 * @param str the <code>char[]</code> to insert 710 * @param str_offset the index in <code>str</code> to start inserting from 711 * @param len the number of characters to insert 712 * @return this <code>StringBuffer</code> 713 * @throws NullPointerException if <code>str</code> is <code>null</code> 714 * @throws StringIndexOutOfBoundsException if any index is out of bounds 715 * @since 1.2 716 */ 717 public synchronized StringBuffer insert(int offset, 718 char[] str, int str_offset, int len) 719 { 720 if (offset < 0 || offset > count || len < 0 721 || str_offset < 0 || str_offset > str.length - len) 722 throw new StringIndexOutOfBoundsException(); 723 ensureCapacity_unsynchronized(count + len); 724 System.arraycopy(value, offset, value, offset + len, count - offset); 725 System.arraycopy(str, str_offset, value, offset, len); 726 count += len; 727 return this; 728 } 729 730 /** 731 * Insert the <code>String</code> value of the argument into this 732 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 733 * to <code>String</code>. 734 * 735 * @param offset the place to insert in this buffer 736 * @param obj the <code>Object</code> to convert and insert 737 * @return this <code>StringBuffer</code> 738 * @exception StringIndexOutOfBoundsException if offset is out of bounds 739 * @see String#valueOf(Object) 740 */ 741 public StringBuffer insert(int offset, Object obj) 742 { 743 return insert(offset, obj == null ? "null" : obj.toString()); 744 } 745 746 /** 747 * Insert the <code>String</code> argument into this 748 * <code>StringBuffer</code>. If str is null, the String "null" is used 749 * instead. 750 * 751 * @param offset the place to insert in this buffer 752 * @param str the <code>String</code> to insert 753 * @return this <code>StringBuffer</code> 754 * @throws StringIndexOutOfBoundsException if offset is out of bounds 755 */ 756 public synchronized StringBuffer insert(int offset, String str) 757 { 758 if (offset < 0 || offset > count) 759 throw new StringIndexOutOfBoundsException(offset); 760 if (str == null) 761 str = "null"; 762 int len = str.count; 763 ensureCapacity_unsynchronized(count + len); 764 System.arraycopy(value, offset, value, offset + len, count - offset); 765 str.getChars(0, len, value, offset); 766 count += len; 767 return this; 768 } 769 770 /** 771 * Insert the <code>CharSequence</code> argument into this 772 * <code>StringBuffer</code>. If the sequence is null, the String 773 * "null" is used instead. 774 * 775 * @param offset the place to insert in this buffer 776 * @param sequence the <code>CharSequence</code> to insert 777 * @return this <code>StringBuffer</code> 778 * @throws IndexOutOfBoundsException if offset is out of bounds 779 * @since 1.5 780 */ 781 public synchronized StringBuffer insert(int offset, CharSequence sequence) 782 { 783 if (sequence == null) 784 sequence = "null"; 785 return insert(offset, sequence, 0, sequence.length()); 786 } 787 788 /** 789 * Insert a subsequence of the <code>CharSequence</code> argument into this 790 * <code>StringBuffer</code>. If the sequence is null, the String 791 * "null" is used instead. 792 * 793 * @param offset the place to insert in this buffer 794 * @param sequence the <code>CharSequence</code> to insert 795 * @param start the starting index of the subsequence 796 * @param end one past the ending index of the subsequence 797 * @return this <code>StringBuffer</code> 798 * @throws IndexOutOfBoundsException if offset, start, 799 * or end are out of bounds 800 * @since 1.5 801 */ 802 public synchronized StringBuffer insert(int offset, CharSequence sequence, 803 int start, int end) 804 { 805 if (sequence == null) 806 sequence = "null"; 807 if (start < 0 || end < 0 || start > end || end > sequence.length()) 808 throw new IndexOutOfBoundsException(); 809 int len = end - start; 810 ensureCapacity_unsynchronized(count + len); 811 System.arraycopy(value, offset, value, offset + len, count - offset); 812 for (int i = start; i < end; ++i) 813 value[offset++] = sequence.charAt(i); 814 count += len; 815 return this; 816 } 817 818 /** 819 * Insert the <code>char[]</code> argument into this 820 * <code>StringBuffer</code>. 821 * 822 * @param offset the place to insert in this buffer 823 * @param data the <code>char[]</code> to insert 824 * @return this <code>StringBuffer</code> 825 * @throws NullPointerException if <code>data</code> is <code>null</code> 826 * @throws StringIndexOutOfBoundsException if offset is out of bounds 827 * @see #insert(int, char[], int, int) 828 */ 829 public StringBuffer insert(int offset, char[] data) 830 { 831 return insert(offset, data, 0, data.length); 832 } 833 834 /** 835 * Insert the <code>String</code> value of the argument into this 836 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 837 * to <code>String</code>. 838 * 839 * @param offset the place to insert in this buffer 840 * @param bool the <code>boolean</code> to convert and insert 841 * @return this <code>StringBuffer</code> 842 * @throws StringIndexOutOfBoundsException if offset is out of bounds 843 * @see String#valueOf(boolean) 844 */ 845 public StringBuffer insert(int offset, boolean bool) 846 { 847 return insert(offset, bool ? "true" : "false"); 848 } 849 850 /** 851 * Insert the <code>char</code> argument into this <code>StringBuffer</code>. 852 * 853 * @param offset the place to insert in this buffer 854 * @param ch the <code>char</code> to insert 855 * @return this <code>StringBuffer</code> 856 * @throws StringIndexOutOfBoundsException if offset is out of bounds 857 */ 858 public synchronized StringBuffer insert(int offset, char ch) 859 { 860 if (offset < 0 || offset > count) 861 throw new StringIndexOutOfBoundsException(offset); 862 ensureCapacity_unsynchronized(count + 1); 863 System.arraycopy(value, offset, value, offset + 1, count - offset); 864 value[offset] = ch; 865 count++; 866 return this; 867 } 868 869 /** 870 * Insert the <code>String</code> value of the argument into this 871 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 872 * to <code>String</code>. 873 * 874 * @param offset the place to insert in this buffer 875 * @param inum the <code>int</code> to convert and insert 876 * @return this <code>StringBuffer</code> 877 * @throws StringIndexOutOfBoundsException if offset is out of bounds 878 * @see String#valueOf(int) 879 */ 880 public StringBuffer insert(int offset, int inum) 881 { 882 return insert(offset, String.valueOf(inum)); 883 } 884 885 /** 886 * Insert the <code>String</code> value of the argument into this 887 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 888 * to <code>String</code>. 889 * 890 * @param offset the place to insert in this buffer 891 * @param lnum the <code>long</code> to convert and insert 892 * @return this <code>StringBuffer</code> 893 * @throws StringIndexOutOfBoundsException if offset is out of bounds 894 * @see String#valueOf(long) 895 */ 896 public StringBuffer insert(int offset, long lnum) 897 { 898 return insert(offset, Long.toString(lnum, 10)); 899 } 900 901 /** 902 * Insert the <code>String</code> value of the argument into this 903 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 904 * to <code>String</code>. 905 * 906 * @param offset the place to insert in this buffer 907 * @param fnum the <code>float</code> to convert and insert 908 * @return this <code>StringBuffer</code> 909 * @throws StringIndexOutOfBoundsException if offset is out of bounds 910 * @see String#valueOf(float) 911 */ 912 public StringBuffer insert(int offset, float fnum) 913 { 914 return insert(offset, Float.toString(fnum)); 915 } 916 917 /** 918 * Insert the <code>String</code> value of the argument into this 919 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 920 * to <code>String</code>. 921 * 922 * @param offset the place to insert in this buffer 923 * @param dnum the <code>double</code> to convert and insert 924 * @return this <code>StringBuffer</code> 925 * @throws StringIndexOutOfBoundsException if offset is out of bounds 926 * @see String#valueOf(double) 927 */ 928 public StringBuffer insert(int offset, double dnum) 929 { 930 return insert(offset, Double.toString(dnum)); 931 } 932 933 /** 934 * Finds the first instance of a substring in this StringBuffer. 935 * 936 * @param str String to find 937 * @return location (base 0) of the String, or -1 if not found 938 * @throws NullPointerException if str is null 939 * @see #indexOf(String, int) 940 * @since 1.4 941 */ 942 public int indexOf(String str) 943 { 944 return indexOf(str, 0); 945 } 946 947 /** 948 * Finds the first instance of a String in this StringBuffer, starting at 949 * a given index. If starting index is less than 0, the search starts at 950 * the beginning of this String. If the starting index is greater than the 951 * length of this String, or the substring is not found, -1 is returned. 952 * 953 * @param str String to find 954 * @param fromIndex index to start the search 955 * @return location (base 0) of the String, or -1 if not found 956 * @throws NullPointerException if str is null 957 * @since 1.4 958 */ 959 public synchronized int indexOf(String str, int fromIndex) 960 { 961 if (fromIndex < 0) 962 fromIndex = 0; 963 int limit = count - str.count; 964 for ( ; fromIndex <= limit; fromIndex++) 965 if (regionMatches(fromIndex, str)) 966 return fromIndex; 967 return -1; 968 } 969 970 /** 971 * Finds the last instance of a substring in this StringBuffer. 972 * 973 * @param str String to find 974 * @return location (base 0) of the String, or -1 if not found 975 * @throws NullPointerException if str is null 976 * @see #lastIndexOf(String, int) 977 * @since 1.4 978 */ 979 public int lastIndexOf(String str) 980 { 981 return lastIndexOf(str, count - str.count); 982 } 983 984 /** 985 * Finds the last instance of a String in this StringBuffer, starting at a 986 * given index. If starting index is greater than the maximum valid index, 987 * then the search begins at the end of this String. If the starting index 988 * is less than zero, or the substring is not found, -1 is returned. 989 * 990 * @param str String to find 991 * @param fromIndex index to start the search 992 * @return location (base 0) of the String, or -1 if not found 993 * @throws NullPointerException if str is null 994 * @since 1.4 995 */ 996 public synchronized int lastIndexOf(String str, int fromIndex) 997 { 998 fromIndex = Math.min(fromIndex, count - str.count); 999 for ( ; fromIndex >= 0; fromIndex--) 1000 if (regionMatches(fromIndex, str)) 1001 return fromIndex; 1002 return -1; 1003 } 1004 1005 /** 1006 * Reverse the characters in this StringBuffer. The same sequence of 1007 * characters exists, but in the reverse index ordering. 1008 * 1009 * @return this <code>StringBuffer</code> 1010 */ 1011 public synchronized StringBuffer reverse() 1012 { 1013 // Call ensureCapacity to enforce copy-on-write. 1014 ensureCapacity_unsynchronized(count); 1015 for (int i = count >> 1, j = count - i; --i >= 0; ++j) 1016 { 1017 char c = value[i]; 1018 value[i] = value[j]; 1019 value[j] = c; 1020 } 1021 return this; 1022 } 1023 1024 /** 1025 * Convert this <code>StringBuffer</code> to a <code>String</code>. The 1026 * String is composed of the characters currently in this StringBuffer. Note 1027 * that the result is a copy, and that future modifications to this buffer 1028 * do not affect the String. 1029 * 1030 * @return the characters in this StringBuffer 1031 */ 1032 public String toString() 1033 { 1034 // The string will set this.shared = true. 1035 return new String(this); 1036 } 1037 1038 /** 1039 * This may reduce the amount of memory used by the StringBuffer, 1040 * by resizing the internal array to remove unused space. However, 1041 * this method is not required to resize, so this behavior cannot 1042 * be relied upon. 1043 * @since 1.5 1044 */ 1045 public synchronized void trimToSize() 1046 { 1047 int wouldSave = value.length - count; 1048 // Some random heuristics: if we save less than 20 characters, who 1049 // cares. 1050 if (wouldSave < 20) 1051 return; 1052 // If we save more than 200 characters, shrink. 1053 // If we save more than 1/4 of the buffer, shrink. 1054 if (wouldSave > 200 || wouldSave * 4 > value.length) 1055 { 1056 char[] newValue = new char[count]; 1057 System.arraycopy(value, 0, newValue, 0, count); 1058 value = newValue; 1059 } 1060 } 1061 1062 /** 1063 * Return the number of code points between two indices in the 1064 * <code>StringBuffer</code>. An unpaired surrogate counts as a 1065 * code point for this purpose. Characters outside the indicated 1066 * range are not examined, even if the range ends in the middle of a 1067 * surrogate pair. 1068 * 1069 * @param start the starting index 1070 * @param end one past the ending index 1071 * @return the number of code points 1072 * @since 1.5 1073 */ 1074 public synchronized int codePointCount(int start, int end) 1075 { 1076 if (start < 0 || end >= count || start > end) 1077 throw new StringIndexOutOfBoundsException(); 1078 1079 int count = 0; 1080 while (start < end) 1081 { 1082 char base = value[start]; 1083 if (base < Character.MIN_HIGH_SURROGATE 1084 || base > Character.MAX_HIGH_SURROGATE 1085 || start == end 1086 || start == count 1087 || value[start + 1] < Character.MIN_LOW_SURROGATE 1088 || value[start + 1] > Character.MAX_LOW_SURROGATE) 1089 { 1090 // Nothing. 1091 } 1092 else 1093 { 1094 // Surrogate pair. 1095 ++start; 1096 } 1097 ++start; 1098 ++count; 1099 } 1100 return count; 1101 } 1102 1103 /** 1104 * Starting at the given index, this counts forward by the indicated 1105 * number of code points, and then returns the resulting index. An 1106 * unpaired surrogate counts as a single code point for this 1107 * purpose. 1108 * 1109 * @param start the starting index 1110 * @param codePoints the number of code points 1111 * @return the resulting index 1112 * @since 1.5 1113 */ 1114 public synchronized int offsetByCodePoints(int start, int codePoints) 1115 { 1116 while (codePoints > 0) 1117 { 1118 char base = value[start]; 1119 if (base < Character.MIN_HIGH_SURROGATE 1120 || base > Character.MAX_HIGH_SURROGATE 1121 || start == count 1122 || value[start + 1] < Character.MIN_LOW_SURROGATE 1123 || value[start + 1] > Character.MAX_LOW_SURROGATE) 1124 { 1125 // Nothing. 1126 } 1127 else 1128 { 1129 // Surrogate pair. 1130 ++start; 1131 } 1132 ++start; 1133 --codePoints; 1134 } 1135 return start; 1136 } 1137 1138 /** 1139 * An unsynchronized version of ensureCapacity, used internally to avoid 1140 * the cost of a second lock on the same object. This also has the side 1141 * effect of duplicating the array, if it was shared (to form copy-on-write 1142 * semantics). 1143 * 1144 * @param minimumCapacity the minimum capacity 1145 * @see #ensureCapacity(int) 1146 */ 1147 private void ensureCapacity_unsynchronized(int minimumCapacity) 1148 { 1149 if (shared || minimumCapacity > value.length) 1150 { 1151 // We don't want to make a larger vector when `shared' is 1152 // set. If we do, then setLength becomes very inefficient 1153 // when repeatedly reusing a StringBuffer in a loop. 1154 int max = (minimumCapacity > value.length 1155 ? value.length * 2 + 2 1156 : value.length); 1157 minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); 1158 char[] nb = new char[minimumCapacity]; 1159 System.arraycopy(value, 0, nb, 0, count); 1160 value = nb; 1161 shared = false; 1162 } 1163 } 1164 1165 /** 1166 * Predicate which determines if a substring of this matches another String 1167 * starting at a specified offset for each String and continuing for a 1168 * specified length. This is more efficient than creating a String to call 1169 * indexOf on. 1170 * 1171 * @param toffset index to start comparison at for this String 1172 * @param other non-null String to compare to region of this 1173 * @return true if regions match, false otherwise 1174 * @see #indexOf(String, int) 1175 * @see #lastIndexOf(String, int) 1176 * @see String#regionMatches(boolean, int, String, int, int) 1177 */ 1178 // GCJ LOCAL: native for gcj. 1179 private native boolean regionMatches(int toffset, String other); 1180 }