1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.lang; 19 20import java.io.IOException; 21import java.io.ObjectInputStream; 22import java.io.ObjectOutputStream; 23import java.io.ObjectStreamField; 24import java.io.Serializable; 25 26/** 27 * StringBuffer is a variable size contiguous indexable array of characters. The 28 * length of the StringBuffer is the number of characters it contains. The 29 * capacity of the StringBuffer is the number of characters it can hold. 30 * <p> 31 * Characters may be inserted at any position up to the length of the 32 * StringBuffer, increasing the length of the StringBuffer. Characters at any 33 * position in the StringBuffer may be replaced, which does not affect the 34 * StringBuffer length. 35 * <p> 36 * The capacity of a StringBuffer may be specified when the StringBuffer is 37 * created. If the capacity of the StringBuffer is exceeded, the capacity is 38 * increased. 39 * 40 * @see String 41 * @see StringBuilder 42 * @since Android 1.0 43 */ 44public final class StringBuffer extends AbstractStringBuilder implements 45 Appendable, Serializable, CharSequence { 46 47 private static final long serialVersionUID = 3388685877147921107L; 48 49 private static final ObjectStreamField serialPersistentFields[] = { 50 new ObjectStreamField("count", int.class), //$NON-NLS-1$ 51 new ObjectStreamField("shared", boolean.class), //$NON-NLS-1$ 52 new ObjectStreamField("value", char[].class), }; //$NON-NLS-1$ 53 54 /** 55 * Constructs a new StringBuffer using the default capacity which is 16. 56 * 57 * @since Android 1.0 58 */ 59 public StringBuffer() { 60 super(); 61 } 62 63 /** 64 * Constructs a new StringBuffer using the specified capacity. 65 * 66 * @param capacity 67 * the initial capacity. 68 * @since Android 1.0 69 */ 70 public StringBuffer(int capacity) { 71 super(capacity); 72 } 73 74 /** 75 * Constructs a new StringBuffer containing the characters in the specified 76 * stringy. The capacity of the new buffer will be the length of the 77 * {@code String} plus the default capacity. 78 * 79 * @param string 80 * the string content with which to initialize the new instance. 81 * @since Android 1.0 82 */ 83 public StringBuffer(String string) { 84 super(string); 85 } 86 87 /** 88 * Constructs a StringBuffer and initializes it with the content from the 89 * specified {@code CharSequence}. The capacity of the new buffer will be 90 * the length of the {@code CharSequence} plus the default capacity. 91 * 92 * @param cs 93 * the content to initialize the instance. 94 * @since Android 1.0 95 */ 96 public StringBuffer(CharSequence cs) { 97 super(cs.toString()); 98 } 99 100 /** 101 * Adds the string representation of the specified boolean to the end of 102 * this StringBuffer. 103 * <p> 104 * If the argument is {@code true} the string {@code "true"} is appended, 105 * otherwise the string {@code "false"} is appended. 106 * </p> 107 * 108 * @param b 109 * the boolean to append. 110 * @return this StringBuffer. 111 * @see String#valueOf(boolean) 112 * @since Android 1.0 113 */ 114 public StringBuffer append(boolean b) { 115 return append(b ? "true" : "false"); //$NON-NLS-1$//$NON-NLS-2$ 116 } 117 118 /** 119 * Adds the specified character to the end of this buffer. 120 * 121 * @param ch 122 * the character to append. 123 * @return this StringBuffer. 124 * @see String#valueOf(char) 125 * @since Android 1.0 126 */ 127 public synchronized StringBuffer append(char ch) { 128 append0(ch); 129 return this; 130 } 131 132 /** 133 * Adds the string representation of the specified double to the end of this 134 * StringBuffer. 135 * 136 * @param d 137 * the double to append. 138 * @return this StringBuffer. 139 * @see String#valueOf(double) 140 * @since Android 1.0 141 */ 142 public StringBuffer append(double d) { 143 return append(Double.toString(d)); 144 } 145 146 /** 147 * Adds the string representation of the specified float to the end of this 148 * StringBuffer. 149 * 150 * @param f 151 * the float to append. 152 * @return this StringBuffer. 153 * @see String#valueOf(float) 154 * @since Android 1.0 155 */ 156 public StringBuffer append(float f) { 157 return append(Float.toString(f)); 158 } 159 160 /** 161 * Adds the string representation of the specified integer to the end of 162 * this StringBuffer. 163 * 164 * @param i 165 * the integer to append. 166 * @return this StringBuffer. 167 * @see String#valueOf(int) 168 * @since Android 1.0 169 */ 170 public StringBuffer append(int i) { 171 return append(Integer.toString(i)); 172 } 173 174 /** 175 * Adds the string representation of the specified long to the end of this 176 * StringBuffer. 177 * 178 * @param l 179 * the long to append. 180 * @return this StringBuffer. 181 * @see String#valueOf(long) 182 * @since Android 1.0 183 */ 184 public StringBuffer append(long l) { 185 return append(Long.toString(l)); 186 } 187 188 /** 189 * Adds the string representation of the specified object to the end of this 190 * StringBuffer. 191 * <p> 192 * If the specified object is {@code null} the string {@code "null"} is 193 * appended, otherwise the objects {@code toString} is used to get its 194 * string representation. 195 * </p> 196 * 197 * @param obj 198 * the object to append (may be null). 199 * @return this StringBuffer. 200 * @see String#valueOf(Object) 201 * @since Android 1.0 202 */ 203 public synchronized StringBuffer append(Object obj) { 204 if (obj == null) { 205 appendNull(); 206 } else { 207 append0(obj.toString()); 208 } 209 return this; 210 } 211 212 /** 213 * Adds the specified string to the end of this buffer. 214 * <p> 215 * If the specified string is {@code null} the string {@code "null"} is 216 * appended, otherwise the contents of the specified string is appended. 217 * </p> 218 * 219 * @param string 220 * the string to append (may be null). 221 * @return this StringBuffer. 222 * @since Android 1.0 223 */ 224 public synchronized StringBuffer append(String string) { 225 append0(string); 226 return this; 227 } 228 229 /** 230 * Adds the specified StringBuffer to the end of this buffer. 231 * <p> 232 * If the specified StringBuffer is {@code null} the string {@code "null"} 233 * is appended, otherwise the contents of the specified StringBuffer is 234 * appended. 235 * </p> 236 * 237 * @param sb 238 * the StringBuffer to append (may be null). 239 * @return this StringBuffer. 240 * @since Android 1.0 241 */ 242 public synchronized StringBuffer append(StringBuffer sb) { 243 if (sb == null) { 244 appendNull(); 245 } else { 246 synchronized (sb) { 247 append0(sb.getValue(), 0, sb.length()); 248 } 249 } 250 return this; 251 } 252 253 /** 254 * Adds the character array to the end of this buffer. 255 * 256 * @param chars 257 * the character array to append. 258 * @return this StringBuffer. 259 * @since Android 1.0 260 */ 261 public synchronized StringBuffer append(char chars[]) { 262 append0(chars); 263 return this; 264 } 265 266 /** 267 * Adds the specified sequence of characters to the end of this buffer. 268 * 269 * @param chars 270 * the character array to append. 271 * @param start 272 * the starting offset. 273 * @param length 274 * the number of characters. 275 * @return this StringBuffer. 276 * @throws ArrayIndexOutOfBoundsException 277 * if {@code length < 0} , {@code start < 0} or {@code start + 278 * length > chars.length}. 279 * @since Android 1.0 280 */ 281 public synchronized StringBuffer append(char chars[], int start, int length) { 282 append0(chars, start, length); 283 return this; 284 } 285 286 /** 287 * Appends the specified CharSequence to this buffer. 288 * <p> 289 * If the specified CharSequence is {@code null} the string {@code "null"} 290 * is appended, otherwise the contents of the specified CharSequence is 291 * appended. 292 * </p> 293 * 294 * @param s 295 * the CharSequence to append. 296 * @return this StringBuffer. 297 * @since Android 1.0 298 */ 299 public synchronized StringBuffer append(CharSequence s) { 300 if (s == null) { 301 appendNull(); 302 } else { 303 append0(s.toString()); 304 } 305 return this; 306 } 307 308 /** 309 * Appends the specified subsequence of the CharSequence to this buffer. 310 * <p> 311 * If the specified CharSequence is {@code null}, then the string {@code 312 * "null"} is used to extract a subsequence. 313 * </p> 314 * 315 * @param s 316 * the CharSequence to append. 317 * @param start 318 * the inclusive start index. 319 * @param end 320 * the exclusive end index. 321 * @return this StringBuffer. 322 * @throws IndexOutOfBoundsException 323 * if {@code start} or {@code end} are negative, {@code start} 324 * is greater than {@code end} or {@code end} is greater than 325 * the length of {@code s}. 326 * @since Android 1.0 327 */ 328 public synchronized StringBuffer append(CharSequence s, int start, int end) { 329 append0(s, start, end); 330 return this; 331 } 332 333 /** 334 * Appends the string representation of the specified Unicode code point to 335 * the end of this buffer. 336 * <p> 337 * The code point is converted to a {@code char[]} as defined by 338 * {@link Character#toChars(int)}. 339 * </p> 340 * 341 * @param codePoint 342 * the Unicode code point to encode and append. 343 * @return this StringBuffer. 344 * @see Character#toChars(int) 345 * @since Android 1.0 346 */ 347 public StringBuffer appendCodePoint(int codePoint) { 348 return append(Character.toChars(codePoint)); 349 } 350 351 @Override 352 public synchronized char charAt(int index) { 353 return super.charAt(index); 354 } 355 356 @Override 357 public synchronized int codePointAt(int index) { 358 return super.codePointAt(index); 359 } 360 361 @Override 362 public synchronized int codePointBefore(int index) { 363 return super.codePointBefore(index); 364 } 365 366 @Override 367 public synchronized int codePointCount(int beginIndex, int endIndex) { 368 return super.codePointCount(beginIndex, endIndex); 369 } 370 371 /** 372 * Deletes a range of characters. 373 * 374 * @param start 375 * the offset of the first character. 376 * @param end 377 * the offset one past the last character. 378 * @return this StringBuffer. 379 * @throws StringIndexOutOfBoundsException 380 * if {@code start < 0}, {@code start > end} or {@code end > 381 * length()}. 382 * @since Android 1.0 383 */ 384 public synchronized StringBuffer delete(int start, int end) { 385 delete0(start, end); 386 return this; 387 } 388 389 /** 390 * Deletes the character at the specified offset. 391 * 392 * @param location 393 * the offset of the character to delete. 394 * @return this StringBuffer. 395 * @throws StringIndexOutOfBoundsException 396 * if {@code location < 0} or {@code location >= length()} 397 * @since Android 1.0 398 */ 399 public synchronized StringBuffer deleteCharAt(int location) { 400 deleteCharAt0(location); 401 return this; 402 } 403 404 @Override 405 public synchronized void ensureCapacity(int min) { 406 super.ensureCapacity(min); 407 } 408 /** 409 * Copies the requested sequence of characters to the {@code char[]} passed 410 * starting at {@code idx}. 411 * 412 * @param start 413 * the starting offset of characters to copy. 414 * @param end 415 * the ending offset of characters to copy. 416 * @param buffer 417 * the destination character array. 418 * @param idx 419 * the starting offset in the character array. 420 * @throws IndexOutOfBoundsException 421 * if {@code start < 0}, {@code end > length()}, {@code start > 422 * end}, {@code index < 0}, {@code end - start > buffer.length - 423 * index} 424 * @since Android 1.0 425 */ 426 @Override 427 public synchronized void getChars(int start, int end, char[] buffer, int idx) { 428 super.getChars(start, end, buffer, idx); 429 } 430 431 @Override 432 public synchronized int indexOf(String subString, int start) { 433 return super.indexOf(subString, start); 434 } 435 436 /** 437 * Inserts the character into this buffer at the specified offset. 438 * 439 * @param index 440 * the index at which to insert. 441 * @param ch 442 * the character to insert. 443 * @return this buffer. 444 * @throws ArrayIndexOutOfBoundsException 445 * if {@code index < 0} or {@code index > length()}. 446 * @since Android 1.0 447 */ 448 public synchronized StringBuffer insert(int index, char ch) { 449 insert0(index, ch); 450 return this; 451 } 452 453 /** 454 * Inserts the string representation of the specified boolean into this 455 * buffer at the specified offset. 456 * 457 * @param index 458 * the index at which to insert. 459 * @param b 460 * the boolean to insert. 461 * @return this buffer. 462 * @throws StringIndexOutOfBoundsException 463 * if {@code index < 0} or {@code index > length()}. 464 * @since Android 1.0 465 */ 466 public StringBuffer insert(int index, boolean b) { 467 return insert(index, b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ 468 } 469 470 /** 471 * Inserts the string representation of the specified integer into this 472 * buffer at the specified offset. 473 * 474 * @param index 475 * the index at which to insert. 476 * @param i 477 * the integer to insert. 478 * @return this buffer. 479 * @throws StringIndexOutOfBoundsException 480 * if {@code index < 0} or {@code index > length()}. 481 * @since Android 1.0 482 */ 483 public StringBuffer insert(int index, int i) { 484 return insert(index, Integer.toString(i)); 485 } 486 487 /** 488 * Inserts the string representation of the specified long into this buffer 489 * at the specified offset. 490 * 491 * @param index 492 * the index at which to insert. 493 * @param l 494 * the long to insert. 495 * @return this buffer. 496 * @throws StringIndexOutOfBoundsException 497 * if {@code index < 0} or {@code index > length()}. 498 * @since Android 1.0 499 */ 500 public StringBuffer insert(int index, long l) { 501 return insert(index, Long.toString(l)); 502 } 503 504 /** 505 * Inserts the string representation of the specified into this buffer 506 * double at the specified offset. 507 * 508 * @param index 509 * the index at which to insert. 510 * @param d 511 * the double to insert. 512 * @return this buffer. 513 * @throws StringIndexOutOfBoundsException 514 * if {@code index < 0} or {@code index > length()}. 515 * @since Android 1.0 516 */ 517 public StringBuffer insert(int index, double d) { 518 return insert(index, Double.toString(d)); 519 } 520 521 /** 522 * Inserts the string representation of the specified float into this buffer 523 * at the specified offset. 524 * 525 * @param index 526 * the index at which to insert. 527 * @param f 528 * the float to insert. 529 * @return this buffer. 530 * @throws StringIndexOutOfBoundsException 531 * if {@code index < 0} or {@code index > length()}. 532 * @since Android 1.0 533 */ 534 public StringBuffer insert(int index, float f) { 535 return insert(index, Float.toString(f)); 536 } 537 538 /** 539 * Inserts the string representation of the specified object into this 540 * buffer at the specified offset. 541 * <p> 542 * If the specified object is {@code null}, the string {@code "null"} is 543 * inserted, otherwise the objects {@code toString} method is used to get 544 * its string representation. 545 * </p> 546 * 547 * @param index 548 * the index at which to insert. 549 * @param obj 550 * the object to insert (may be null). 551 * @return this buffer. 552 * @throws StringIndexOutOfBoundsException 553 * if {@code index < 0} or {@code index > length()}. 554 * @since Android 1.0 555 */ 556 public StringBuffer insert(int index, Object obj) { 557 return insert(index, obj == null ? "null" : obj.toString()); //$NON-NLS-1$ 558 } 559 560 /** 561 * Inserts the string into this buffer at the specified offset. 562 * <p> 563 * If the specified string is {@code null}, the string {@code "null"} is 564 * inserted, otherwise the contents of the string is inserted. 565 * </p> 566 * 567 * @param index 568 * the index at which to insert. 569 * @param string 570 * the string to insert (may be null). 571 * @return this buffer. 572 * @throws StringIndexOutOfBoundsException 573 * if {@code index < 0} or {@code index > length()}. 574 * @since Android 1.0 575 */ 576 public synchronized StringBuffer insert(int index, String string) { 577 insert0(index, string); 578 return this; 579 } 580 581 /** 582 * Inserts the character array into this buffer at the specified offset. 583 * 584 * @param index 585 * the index at which to insert. 586 * @param chars 587 * the character array to insert. 588 * @return this buffer. 589 * @throws StringIndexOutOfBoundsException 590 * if {@code index < 0} or {@code index > length()}. 591 * @since Android 1.0 592 */ 593 public synchronized StringBuffer insert(int index, char[] chars) { 594 insert0(index, chars); 595 return this; 596 } 597 598 /** 599 * Inserts the specified subsequence of characters into this buffer at the 600 * specified index. 601 * 602 * @param index 603 * the index at which to insert. 604 * @param chars 605 * the character array to insert. 606 * @param start 607 * the starting offset. 608 * @param length 609 * the number of characters. 610 * @return this buffer. 611 * @throws StringIndexOutOfBoundsException 612 * if {@code length < 0}, {@code start < 0}, {@code start + 613 * length > chars.length}, {@code index < 0} or {@code index > 614 * length()} 615 * @since Android 1.0 616 */ 617 public synchronized StringBuffer insert(int index, char chars[], int start, 618 int length) { 619 insert0(index, chars, start, length); 620 return this; 621 } 622 623 /** 624 * Inserts the specified CharSequence into this buffer at the specified 625 * index. 626 * <p> 627 * If the specified CharSequence is {@code null}, the string {@code "null"} 628 * is inserted, otherwise the contents of the CharSequence. 629 * </p> 630 * 631 * @param index 632 * The index at which to insert. 633 * @param s 634 * The char sequence to insert. 635 * @return this buffer. 636 * @throws IndexOutOfBoundsException 637 * if {@code index < 0} or {@code index > length()}. 638 * @since Android 1.0 639 */ 640 public synchronized StringBuffer insert(int index, CharSequence s) { 641 insert0(index, s == null ? "null" : s.toString()); //$NON-NLS-1$ 642 return this; 643 } 644 645 /** 646 * Inserts the specified subsequence into this buffer at the specified 647 * index. 648 * <p> 649 * If the specified CharSequence is {@code null}, the string {@code "null"} 650 * is inserted, otherwise the contents of the CharSequence. 651 * </p> 652 * 653 * @param index 654 * The index at which to insert. 655 * @param s 656 * The char sequence to insert. 657 * @param start 658 * The inclusive start index in the char sequence. 659 * @param end 660 * The exclusive end index in the char sequence. 661 * @return this buffer. 662 * @throws IndexOutOfBoundsException 663 * if {@code index} is negative or greater than the current 664 * length, {@code start} or {@code end} are negative, {@code 665 * start} is greater than {@code end} or {@code end} is greater 666 * than the length of {@code s}. 667 * @since Android 1.0 668 */ 669 public synchronized StringBuffer insert(int index, CharSequence s, 670 int start, int end) { 671 insert0(index, s, start, end); 672 return this; 673 } 674 675 @Override 676 public synchronized int lastIndexOf(String subString, int start) { 677 return super.lastIndexOf(subString, start); 678 } 679 680 @Override 681 public synchronized int offsetByCodePoints(int index, int codePointOffset) { 682 return super.offsetByCodePoints(index, codePointOffset); 683 } 684 685 /** 686 * Replaces the characters in the specified range with the contents of the 687 * specified string. 688 * 689 * @param start 690 * the inclusive begin index. 691 * @param end 692 * the exclusive end index. 693 * @param string 694 * the string that will replace the contents in the range. 695 * @return this buffer. 696 * @throws StringIndexOutOfBoundsException 697 * if {@code start} or {@code end} are negative, {@code start} 698 * is greater than {@code end} or {@code end} is greater than 699 * the length of {@code s}. 700 * @since Android 1.0 701 */ 702 public synchronized StringBuffer replace(int start, int end, String string) { 703 replace0(start, end, string); 704 return this; 705 } 706 707 /** 708 * Reverses the order of characters in this buffer. 709 * 710 * @return this buffer. 711 * @since Android 1.0 712 */ 713 public synchronized StringBuffer reverse() { 714 reverse0(); 715 return this; 716 } 717 718 @Override 719 public synchronized void setCharAt(int index, char ch) { 720 super.setCharAt(index, ch); 721 } 722 723 @Override 724 public synchronized void setLength(int length) { 725 super.setLength(length); 726 } 727 728 @Override 729 public synchronized CharSequence subSequence(int start, int end) { 730 return super.substring(start, end); 731 } 732 733 @Override 734 public synchronized String substring(int start) { 735 return super.substring(start); 736 } 737 738 @Override 739 public synchronized String substring(int start, int end) { 740 return super.substring(start, end); 741 } 742 743 @Override 744 public synchronized String toString() { 745 return super.toString(); 746 } 747 748 @Override 749 public synchronized void trimToSize() { 750 super.trimToSize(); 751 } 752 753 private synchronized void writeObject(ObjectOutputStream out) 754 throws IOException { 755 ObjectOutputStream.PutField fields = out.putFields(); 756 fields.put("count", length()); //$NON-NLS-1$ 757 fields.put("shared", false); //$NON-NLS-1$ 758 fields.put("value", getValue()); //$NON-NLS-1$ 759 out.writeFields(); 760 } 761 762 private void readObject(ObjectInputStream in) throws IOException, 763 ClassNotFoundException { 764 ObjectInputStream.GetField fields = in.readFields(); 765 int count = fields.get("count", 0); //$NON-NLS-1$ 766 char[] value = (char[]) fields.get("value", null); //$NON-NLS-1$ 767 set(value, count); 768 } 769} 770