| GNU Classpath (0.95) | |
| Frames | No Frames |
1: /* StringBuffer.java -- Growable strings 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: package java.lang; 40: 41: import java.io.Serializable; 42: 43: /** 44: * <code>StringBuffer</code> represents a changeable <code>String</code>. 45: * It provides the operations required to modify the 46: * <code>StringBuffer</code>, including insert, replace, delete, append, 47: * and reverse. It is thread-safe; meaning that all modifications to a buffer 48: * are in synchronized methods. 49: * 50: * <p><code>StringBuffer</code>s are variable-length in nature, so even if 51: * you initialize them to a certain size, they can still grow larger than 52: * that. <em>Capacity</em> indicates the number of characters the 53: * <code>StringBuffer</code> can have in it before it has to grow (growing 54: * the char array is an expensive operation involving <code>new</code>). 55: * 56: * <p>Incidentally, compilers often implement the String operator "+" 57: * by using a <code>StringBuffer</code> operation:<br> 58: * <code>a + b</code><br> 59: * is the same as<br> 60: * <code>new StringBuffer().append(a).append(b).toString()</code>. 61: * 62: * <p>Classpath's StringBuffer is capable of sharing memory with Strings for 63: * efficiency. This will help when a StringBuffer is converted to a String 64: * and the StringBuffer is not changed after that (quite common when performing 65: * string concatenation). 66: * 67: * @author Paul Fisher 68: * @author John Keiser 69: * @author Tom Tromey 70: * @author Eric Blake (ebb9@email.byu.edu) 71: * @see String 72: * @since 1.0 73: * @status updated to 1.4 74: */ 75: public final class StringBuffer 76: implements Serializable, CharSequence, Appendable 77: { 78: // Implementation note: if you change this class, you usually will 79: // want to change StringBuilder as well. 80: 81: /** 82: * Compatible with JDK 1.0+. 83: */ 84: private static final long serialVersionUID = 3388685877147921107L; 85: 86: /** 87: * Index of next available character (and thus the size of the current 88: * string contents). Note that this has permissions set this way so that 89: * String can get the value. 90: * 91: * @serial the number of characters in the buffer 92: */ 93: int count; 94: 95: /** 96: * The buffer. Note that this has permissions set this way so that String 97: * can get the value. 98: * 99: * @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 in the 156: * specified <code>CharSequence</code>. Initial capacity will be the 157: * length of the sequence plus 16; if the sequence reports a length 158: * less than or equal to 0, then the initial capacity will be 16. 159: * 160: * @param seq the initializing <code>CharSequence</code> 161: * @throws NullPointerException if str is null 162: * @since 1.5 163: */ 164: public StringBuffer(CharSequence seq) 165: { 166: int len = seq.length(); 167: count = len <= 0 ? 0 : len; 168: value = new char[count + DEFAULT_CAPACITY]; 169: for (int i = 0; i < len; ++i) 170: value[i] = seq.charAt(i); 171: } 172: 173: /** 174: * Get the length of the <code>String</code> this <code>StringBuffer</code> 175: * would create. Not to be confused with the <em>capacity</em> of the 176: * <code>StringBuffer</code>. 177: * 178: * @return the length of this <code>StringBuffer</code> 179: * @see #capacity() 180: * @see #setLength(int) 181: */ 182: public synchronized int length() 183: { 184: return count; 185: } 186: 187: /** 188: * Get the total number of characters this <code>StringBuffer</code> can 189: * support before it must be grown. Not to be confused with <em>length</em>. 190: * 191: * @return the capacity of this <code>StringBuffer</code> 192: * @see #length() 193: * @see #ensureCapacity(int) 194: */ 195: public synchronized int capacity() 196: { 197: return value.length; 198: } 199: 200: /** 201: * Increase the capacity of this <code>StringBuffer</code>. This will 202: * ensure that an expensive growing operation will not occur until 203: * <code>minimumCapacity</code> is reached. The buffer is grown to the 204: * larger of <code>minimumCapacity</code> and 205: * <code>capacity() * 2 + 2</code>, if it is not already large enough. 206: * 207: * @param minimumCapacity the new capacity 208: * @see #capacity() 209: */ 210: public synchronized void ensureCapacity(int minimumCapacity) 211: { 212: ensureCapacity_unsynchronized(minimumCapacity); 213: } 214: 215: /** 216: * Set the length of this StringBuffer. If the new length is greater than 217: * the current length, all the new characters are set to '\0'. If the new 218: * length is less than the current length, the first <code>newLength</code> 219: * characters of the old array will be preserved, and the remaining 220: * characters are truncated. 221: * 222: * @param newLength the new length 223: * @throws IndexOutOfBoundsException if the new length is negative 224: * (while unspecified, this is a StringIndexOutOfBoundsException) 225: * @see #length() 226: */ 227: public synchronized void setLength(int newLength) 228: { 229: if (newLength < 0) 230: throw new StringIndexOutOfBoundsException(newLength); 231: 232: int valueLength = value.length; 233: 234: /* Always call ensureCapacity_unsynchronized in order to preserve 235: copy-on-write semantics. */ 236: ensureCapacity_unsynchronized(newLength); 237: 238: if (newLength < valueLength) 239: { 240: /* If the StringBuffer's value just grew, then we know that 241: value is newly allocated and the region between count and 242: newLength is filled with '\0'. */ 243: count = newLength; 244: } 245: else 246: { 247: /* The StringBuffer's value doesn't need to grow. However, 248: we should clear out any cruft that may exist. */ 249: while (count < newLength) 250: value[count++] = '\0'; 251: } 252: } 253: 254: /** 255: * Get the character at the specified index. 256: * 257: * @param index the index of the character to get, starting at 0 258: * @return the character at the specified index 259: * @throws IndexOutOfBoundsException if index is negative or >= length() 260: */ 261: public synchronized char charAt(int index) 262: { 263: if (index < 0 || index >= count) 264: throw new StringIndexOutOfBoundsException(index); 265: return value[index]; 266: } 267: 268: /** 269: * Get the code point at the specified index. This is like #charAt(int), 270: * but if the character is the start of a surrogate pair, and the 271: * following character completes the pair, then the corresponding 272: * supplementary code point is returned. 273: * @param index the index of the codepoint to get, starting at 0 274: * @return the codepoint at the specified index 275: * @throws IndexOutOfBoundsException if index is negative or >= length() 276: * @since 1.5 277: */ 278: public synchronized int codePointAt(int index) 279: { 280: return Character.codePointAt(value, index, count); 281: } 282: 283: /** 284: * Get the code point before the specified index. This is like 285: * #codePointAt(int), but checks the characters at <code>index-1</code> and 286: * <code>index-2</code> to see if they form a supplementary code point. 287: * @param index the index just past the codepoint to get, starting at 0 288: * @return the codepoint at the specified index 289: * @throws IndexOutOfBoundsException if index is negative or >= length() 290: * @since 1.5 291: */ 292: public synchronized int codePointBefore(int index) 293: { 294: // Character.codePointBefore() doesn't perform this check. We 295: // could use the CharSequence overload, but this is just as easy. 296: if (index >= count) 297: throw new IndexOutOfBoundsException(); 298: return Character.codePointBefore(value, index, 1); 299: } 300: 301: /** 302: * Get the specified array of characters. <code>srcOffset - srcEnd</code> 303: * characters will be copied into the array you pass in. 304: * 305: * @param srcOffset the index to start copying from (inclusive) 306: * @param srcEnd the index to stop copying from (exclusive) 307: * @param dst the array to copy into 308: * @param dstOffset the index to start copying into 309: * @throws NullPointerException if dst is null 310: * @throws IndexOutOfBoundsException if any source or target indices are 311: * out of range (while unspecified, source problems cause a 312: * StringIndexOutOfBoundsException, and dest problems cause an 313: * ArrayIndexOutOfBoundsException) 314: * @see System#arraycopy(Object, int, Object, int, int) 315: */ 316: public synchronized void getChars(int srcOffset, int srcEnd, 317: char[] dst, int dstOffset) 318: { 319: if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset) 320: throw new StringIndexOutOfBoundsException(); 321: VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); 322: } 323: 324: /** 325: * Set the character at the specified index. 326: * 327: * @param index the index of the character to set starting at 0 328: * @param ch the value to set that character to 329: * @throws IndexOutOfBoundsException if index is negative or >= length() 330: * (while unspecified, this is a StringIndexOutOfBoundsException) 331: */ 332: public synchronized void setCharAt(int index, char ch) 333: { 334: if (index < 0 || index >= count) 335: throw new StringIndexOutOfBoundsException(index); 336: // Call ensureCapacity to enforce copy-on-write. 337: ensureCapacity_unsynchronized(count); 338: value[index] = ch; 339: } 340: 341: /** 342: * Append the <code>String</code> value of the argument to this 343: * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 344: * to <code>String</code>. 345: * 346: * @param obj the <code>Object</code> to convert and append 347: * @return this <code>StringBuffer</code> 348: * @see String#valueOf(Object) 349: * @see #append(String) 350: */ 351: public StringBuffer append(Object obj) 352: { 353: return append(obj == null ? "null" : obj.toString()); 354: } 355: 356: /** 357: * Append the <code>String</code> to this <code>StringBuffer</code>. If 358: * str is null, the String "null" is appended. 359: * 360: * @param str the <code>String</code> to append 361: * @return this <code>StringBuffer</code> 362: */ 363: public synchronized StringBuffer append(String str) 364: { 365: if (str == null) 366: str = "null"; 367: int len = str.count; 368: ensureCapacity_unsynchronized(count + len); 369: str.getChars(0, len, value, count); 370: count += len; 371: return this; 372: } 373: 374: /** 375: * Append the <code>StringBuffer</code> value of the argument to this 376: * <code>StringBuffer</code>. This behaves the same as 377: * <code>append((Object) stringBuffer)</code>, except it is more efficient. 378: * 379: * @param stringBuffer the <code>StringBuffer</code> to convert and append 380: * @return this <code>StringBuffer</code> 381: * @see #append(Object) 382: * @since 1.4 383: */ 384: public synchronized StringBuffer append(StringBuffer stringBuffer) 385: { 386: if (stringBuffer == null) 387: return append("null"); 388: synchronized (stringBuffer) 389: { 390: int len = stringBuffer.count; 391: ensureCapacity_unsynchronized(count + len); 392: VMSystem.arraycopy(stringBuffer.value, 0, value, count, len); 393: count += len; 394: } 395: return this; 396: } 397: 398: /** 399: * Append the <code>char</code> array to this <code>StringBuffer</code>. 400: * This is similar (but more efficient) than 401: * <code>append(new String(data))</code>, except in the case of null. 402: * 403: * @param data the <code>char[]</code> to append 404: * @return this <code>StringBuffer</code> 405: * @throws NullPointerException if <code>str</code> is <code>null</code> 406: * @see #append(char[], int, int) 407: */ 408: public StringBuffer append(char[] data) 409: { 410: return append(data, 0, data.length); 411: } 412: 413: /** 414: * Append part of the <code>char</code> array to this 415: * <code>StringBuffer</code>. This is similar (but more efficient) than 416: * <code>append(new String(data, offset, count))</code>, except in the case 417: * of null. 418: * 419: * @param data the <code>char[]</code> to append 420: * @param offset the start location in <code>str</code> 421: * @param count the number of characters to get from <code>str</code> 422: * @return this <code>StringBuffer</code> 423: * @throws NullPointerException if <code>str</code> is <code>null</code> 424: * @throws IndexOutOfBoundsException if offset or count is out of range 425: * (while unspecified, this is a StringIndexOutOfBoundsException) 426: */ 427: public synchronized StringBuffer append(char[] data, int offset, int count) 428: { 429: if (offset < 0 || count < 0 || offset > data.length - count) 430: throw new StringIndexOutOfBoundsException(); 431: ensureCapacity_unsynchronized(this.count + count); 432: VMSystem.arraycopy(data, offset, value, this.count, count); 433: this.count += count; 434: return this; 435: } 436: 437: /** 438: * Append the code point to this <code>StringBuffer</code>. 439: * This is like #append(char), but will append two characters 440: * if a supplementary code point is given. 441: * 442: * @param code the code point to append 443: * @return this <code>StringBuffer</code> 444: * @see Character#toChars(int, char[], int) 445: * @since 1.5 446: */ 447: public synchronized StringBuffer appendCodePoint(int code) 448: { 449: int len = Character.charCount(code); 450: ensureCapacity_unsynchronized(count + len); 451: Character.toChars(code, value, count); 452: count += len; 453: return this; 454: } 455: 456: /** 457: * Append the <code>String</code> value of the argument to this 458: * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 459: * to <code>String</code>. 460: * 461: * @param bool the <code>boolean</code> to convert and append 462: * @return this <code>StringBuffer</code> 463: * @see String#valueOf(boolean) 464: */ 465: public StringBuffer append(boolean bool) 466: { 467: return append(bool ? "true" : "false"); 468: } 469: 470: /** 471: * Append the <code>char</code> to this <code>StringBuffer</code>. 472: * 473: * @param ch the <code>char</code> to append 474: * @return this <code>StringBuffer</code> 475: */ 476: public synchronized StringBuffer append(char ch) 477: { 478: ensureCapacity_unsynchronized(count + 1); 479: value[count++] = ch; 480: return this; 481: } 482: 483: /** 484: * Append the characters in the <code>CharSequence</code> to this 485: * buffer. 486: * 487: * @param seq the <code>CharSequence</code> providing the characters 488: * @return this <code>StringBuffer</code> 489: * @since 1.5 490: */ 491: public synchronized StringBuffer append(CharSequence seq) 492: { 493: return append(seq, 0, seq.length()); 494: } 495: 496: /** 497: * Append some characters from the <code>CharSequence</code> to this 498: * buffer. If the argument is null, the four characters "null" are 499: * appended. 500: * 501: * @param seq the <code>CharSequence</code> providing the characters 502: * @param start the starting index 503: * @param end one past the final index 504: * @return this <code>StringBuffer</code> 505: * @since 1.5 506: */ 507: public synchronized StringBuffer append(CharSequence seq, int start, int end) 508: { 509: if (seq == null) 510: return append("null"); 511: if (end - start > 0) 512: { 513: ensureCapacity_unsynchronized(count + end - start); 514: for (; start < end; ++start) 515: value[count++] = seq.charAt(start); 516: } 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: // This is native in libgcj, for efficiency. 530: public StringBuffer append(int inum) 531: { 532: return append(String.valueOf(inum)); 533: } 534: 535: /** 536: * Append the <code>String</code> value of the argument to this 537: * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 538: * to <code>String</code>. 539: * 540: * @param lnum the <code>long</code> to convert and append 541: * @return this <code>StringBuffer</code> 542: * @see String#valueOf(long) 543: */ 544: public StringBuffer append(long lnum) 545: { 546: return append(Long.toString(lnum, 10)); 547: } 548: 549: /** 550: * Append the <code>String</code> value of the argument to this 551: * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 552: * to <code>String</code>. 553: * 554: * @param fnum the <code>float</code> to convert and append 555: * @return this <code>StringBuffer</code> 556: * @see String#valueOf(float) 557: */ 558: public StringBuffer append(float fnum) 559: { 560: return append(Float.toString(fnum)); 561: } 562: 563: /** 564: * Append the <code>String</code> value of the argument to this 565: * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 566: * to <code>String</code>. 567: * 568: * @param dnum the <code>double</code> to convert and append 569: * @return this <code>StringBuffer</code> 570: * @see String#valueOf(double) 571: */ 572: public StringBuffer append(double dnum) 573: { 574: return append(Double.toString(dnum)); 575: } 576: 577: /** 578: * Delete characters from this <code>StringBuffer</code>. 579: * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is 580: * harmless for end to be larger than length(). 581: * 582: * @param start the first character to delete 583: * @param end the index after the last character to delete 584: * @return this <code>StringBuffer</code> 585: * @throws StringIndexOutOfBoundsException if start or end are out of bounds 586: * @since 1.2 587: */ 588: public synchronized StringBuffer delete(int start, int end) 589: { 590: if (start < 0 || start > count || start > end) 591: throw new StringIndexOutOfBoundsException(start); 592: if (end > count) 593: end = count; 594: // This will unshare if required. 595: ensureCapacity_unsynchronized(count); 596: if (count - end != 0) 597: VMSystem.arraycopy(value, end, value, start, count - end); 598: count -= end - start; 599: return this; 600: } 601: 602: /** 603: * Delete a character from this <code>StringBuffer</code>. 604: * 605: * @param index the index of the character to delete 606: * @return this <code>StringBuffer</code> 607: * @throws StringIndexOutOfBoundsException if index is out of bounds 608: * @since 1.2 609: */ 610: public StringBuffer deleteCharAt(int index) 611: { 612: return delete(index, index + 1); 613: } 614: 615: /** 616: * Replace characters between index <code>start</code> (inclusive) and 617: * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code> 618: * is larger than the size of this StringBuffer, all characters after 619: * <code>start</code> are replaced. 620: * 621: * @param start the beginning index of characters to delete (inclusive) 622: * @param end the ending index of characters to delete (exclusive) 623: * @param str the new <code>String</code> to insert 624: * @return this <code>StringBuffer</code> 625: * @throws StringIndexOutOfBoundsException if start or end are out of bounds 626: * @throws NullPointerException if str is null 627: * @since 1.2 628: */ 629: public synchronized StringBuffer replace(int start, int end, String str) 630: { 631: if (start < 0 || start > count || start > end) 632: throw new StringIndexOutOfBoundsException(start); 633: 634: int len = str.count; 635: // Calculate the difference in 'count' after the replace. 636: int delta = len - (end > count ? count : end) + start; 637: ensureCapacity_unsynchronized(count + delta); 638: 639: if (delta != 0 && end < count) 640: VMSystem.arraycopy(value, end, value, end + delta, count - end); 641: 642: str.getChars(0, len, value, start); 643: count += delta; 644: return this; 645: } 646: 647: /** 648: * Creates a substring of this StringBuffer, starting at a specified index 649: * and ending at the end of this StringBuffer. 650: * 651: * @param beginIndex index to start substring (base 0) 652: * @return new String which is a substring of this StringBuffer 653: * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds 654: * @see #substring(int, int) 655: * @since 1.2 656: */ 657: public String substring(int beginIndex) 658: { 659: return substring(beginIndex, count); 660: } 661: 662: /** 663: * Creates a substring of this StringBuffer, starting at a specified index 664: * and ending at one character before a specified index. This is implemented 665: * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy 666: * the CharSequence interface. 667: * 668: * @param beginIndex index to start at (inclusive, base 0) 669: * @param endIndex index to end at (exclusive) 670: * @return new String which is a substring of this StringBuffer 671: * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of 672: * bounds 673: * @see #substring(int, int) 674: * @since 1.4 675: */ 676: public CharSequence subSequence(int beginIndex, int endIndex) 677: { 678: return substring(beginIndex, endIndex); 679: } 680: 681: /** 682: * Creates a substring of this StringBuffer, starting at a specified index 683: * and ending at one character before a specified index. 684: * 685: * @param beginIndex index to start at (inclusive, base 0) 686: * @param endIndex index to end at (exclusive) 687: * @return new String which is a substring of this StringBuffer 688: * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out 689: * of bounds 690: * @since 1.2 691: */ 692: public synchronized String substring(int beginIndex, int endIndex) 693: { 694: int len = endIndex - beginIndex; 695: if (beginIndex < 0 || endIndex > count || endIndex < beginIndex) 696: throw new StringIndexOutOfBoundsException(); 697: if (len == 0) 698: return ""; 699: // Don't copy unless substring is smaller than 1/4 of the buffer. 700: boolean share_buffer = ((len << 2) >= value.length); 701: if (share_buffer) 702: this.shared = true; 703: // Package constructor avoids an array copy. 704: return new String(value, beginIndex, len, share_buffer); 705: } 706: 707: /** 708: * Insert a subarray of the <code>char[]</code> argument into this 709: * <code>StringBuffer</code>. 710: * 711: * @param offset the place to insert in this buffer 712: * @param str the <code>char[]</code> to insert 713: * @param str_offset the index in <code>str</code> to start inserting from 714: * @param len the number of characters to insert 715: * @return this <code>StringBuffer</code> 716: * @throws NullPointerException if <code>str</code> is <code>null</code> 717: * @throws StringIndexOutOfBoundsException if any index is out of bounds 718: * @since 1.2 719: */ 720: public synchronized StringBuffer insert(int offset, 721: char[] str, int str_offset, int len) 722: { 723: if (offset < 0 || offset > count || len < 0 724: || str_offset < 0 || str_offset > str.length - len) 725: throw new StringIndexOutOfBoundsException(); 726: ensureCapacity_unsynchronized(count + len); 727: VMSystem.arraycopy(value, offset, value, offset + len, count - offset); 728: VMSystem.arraycopy(str, str_offset, value, offset, len); 729: count += len; 730: return this; 731: } 732: 733: /** 734: * Insert the <code>String</code> value of the argument into this 735: * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 736: * to <code>String</code>. 737: * 738: * @param offset the place to insert in this buffer 739: * @param obj the <code>Object</code> to convert and insert 740: * @return this <code>StringBuffer</code> 741: * @exception StringIndexOutOfBoundsException if offset is out of bounds 742: * @see String#valueOf(Object) 743: */ 744: public StringBuffer insert(int offset, Object obj) 745: { 746: return insert(offset, obj == null ? "null" : obj.toString()); 747: } 748: 749: /** 750: * Insert the <code>String</code> argument into this 751: * <code>StringBuffer</code>. If str is null, the String "null" is used 752: * instead. 753: * 754: * @param offset the place to insert in this buffer 755: * @param str the <code>String</code> to insert 756: * @return this <code>StringBuffer</code> 757: * @throws StringIndexOutOfBoundsException if offset is out of bounds 758: */ 759: public synchronized StringBuffer insert(int offset, String str) 760: { 761: if (offset < 0 || offset > count) 762: throw new StringIndexOutOfBoundsException(offset); 763: if (str == null) 764: str = "null"; 765: int len = str.count; 766: ensureCapacity_unsynchronized(count + len); 767: VMSystem.arraycopy(value, offset, value, offset + len, count - offset); 768: str.getChars(0, len, value, offset); 769: count += len; 770: return this; 771: } 772: 773: /** 774: * Insert the <code>CharSequence</code> argument into this 775: * <code>StringBuffer</code>. If the sequence is null, the String 776: * "null" is used instead. 777: * 778: * @param offset the place to insert in this buffer 779: * @param sequence the <code>CharSequence</code> to insert 780: * @return this <code>StringBuffer</code> 781: * @throws IndexOutOfBoundsException if offset is out of bounds 782: * @since 1.5 783: */ 784: public synchronized StringBuffer insert(int offset, CharSequence sequence) 785: { 786: if (sequence == null) 787: sequence = "null"; 788: return insert(offset, sequence, 0, sequence.length()); 789: } 790: 791: /** 792: * Insert a subsequence of the <code>CharSequence</code> argument into this 793: * <code>StringBuffer</code>. If the sequence is null, the String 794: * "null" is used instead. 795: * 796: * @param offset the place to insert in this buffer 797: * @param sequence the <code>CharSequence</code> to insert 798: * @param start the starting index of the subsequence 799: * @param end one past the ending index of the subsequence 800: * @return this <code>StringBuffer</code> 801: * @throws IndexOutOfBoundsException if offset, start, 802: * or end are out of bounds 803: * @since 1.5 804: */ 805: public synchronized StringBuffer insert(int offset, CharSequence sequence, 806: int start, int end) 807: { 808: if (sequence == null) 809: sequence = "null"; 810: if (start < 0 || end < 0 || start > end || end > sequence.length()) 811: throw new IndexOutOfBoundsException(); 812: int len = end - start; 813: ensureCapacity_unsynchronized(count + len); 814: VMSystem.arraycopy(value, offset, value, offset + len, count - offset); 815: for (int i = start; i < end; ++i) 816: value[offset++] = sequence.charAt(i); 817: count += len; 818: return this; 819: } 820: 821: /** 822: * Insert the <code>char[]</code> argument into this 823: * <code>StringBuffer</code>. 824: * 825: * @param offset the place to insert in this buffer 826: * @param data the <code>char[]</code> to insert 827: * @return this <code>StringBuffer</code> 828: * @throws NullPointerException if <code>data</code> is <code>null</code> 829: * @throws StringIndexOutOfBoundsException if offset is out of bounds 830: * @see #insert(int, char[], int, int) 831: */ 832: public StringBuffer insert(int offset, char[] data) 833: { 834: return insert(offset, data, 0, data.length); 835: } 836: 837: /** 838: * Insert the <code>String</code> value of the argument into this 839: * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert 840: * to <code>String</code>. 841: * 842: * @param offset the place to insert in this buffer 843: * @param bool the <code>boolean</code> to convert and insert 844: * @return this <code>StringBuffer</code> 845: * @throws StringIndexOutOfBoundsException if offset is out of bounds 846: * @see String#valueOf(boolean) 847: */ 848: public