1 /*
   2  * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 
  28 import java.util.Arrays;
  29 import jdk.internal.HotSpotIntrinsicCandidate;
  30 
  31 /**
  32  * A thread-safe, mutable sequence of characters.
  33  * A string buffer is like a {@link String}, but can be modified. At any
  34  * point in time it contains some particular sequence of characters, but
  35  * the length and content of the sequence can be changed through certain
  36  * method calls.
  37  * <p>
  38  * String buffers are safe for use by multiple threads. The methods
  39  * are synchronized where necessary so that all the operations on any
  40  * particular instance behave as if they occur in some serial order
  41  * that is consistent with the order of the method calls made by each of
  42  * the individual threads involved.
  43  * <p>
  44  * The principal operations on a {@code StringBuffer} are the
  45  * {@code append} and {@code insert} methods, which are
  46  * overloaded so as to accept data of any type. Each effectively
  47  * converts a given datum to a string and then appends or inserts the
  48  * characters of that string to the string buffer. The
  49  * {@code append} method always adds these characters at the end
  50  * of the buffer; the {@code insert} method adds the characters at
  51  * a specified point.
  52  * <p>
  53  * For example, if {@code z} refers to a string buffer object
  54  * whose current contents are {@code "start"}, then
  55  * the method call {@code z.append("le")} would cause the string
  56  * buffer to contain {@code "startle"}, whereas
  57  * {@code z.insert(4, "le")} would alter the string buffer to
  58  * contain {@code "starlet"}.
  59  * <p>
  60  * In general, if sb refers to an instance of a {@code StringBuffer},
  61  * then {@code sb.append(x)} has the same effect as
  62  * {@code sb.insert(sb.length(), x)}.
  63  * <p>
  64  * Whenever an operation occurs involving a source sequence (such as
  65  * appending or inserting from a source sequence), this class synchronizes
  66  * only on the string buffer performing the operation, not on the source.
  67  * Note that while {@code StringBuffer} is designed to be safe to use
  68  * concurrently from multiple threads, if the constructor or the
  69  * {@code append} or {@code insert} operation is passed a source sequence
  70  * that is shared across threads, the calling code must ensure
  71  * that the operation has a consistent and unchanging view of the source
  72  * sequence for the duration of the operation.
  73  * This could be satisfied by the caller holding a lock during the
  74  * operation's call, by using an immutable source sequence, or by not
  75  * sharing the source sequence across threads.
  76  * <p>
  77  * Every string buffer has a capacity. As long as the length of the
  78  * character sequence contained in the string buffer does not exceed
  79  * the capacity, it is not necessary to allocate a new internal
  80  * buffer array. If the internal buffer overflows, it is
  81  * automatically made larger.
  82  * <p>
  83  * Unless otherwise noted, passing a {@code null} argument to a constructor
  84  * or method in this class will cause a {@link NullPointerException} to be
  85  * thrown.
  86  * <p>
  87  * As of  release JDK 5, this class has been supplemented with an equivalent
  88  * class designed for use by a single thread, {@link StringBuilder}.  The
  89  * {@code StringBuilder} class should generally be used in preference to
  90  * this one, as it supports all of the same operations but it is faster, as
  91  * it performs no synchronization.
  92  *
  93  * @apiNote
  94  * {@code StringBuffer} implements {@code Comparable} but does not override
  95  * {@link Object#equals equals}. Thus, the natural ordering of {@code StringBuffer}
  96  * is inconsistent with equals. Care should be exercised if {@code StringBuffer}
  97  * objects are used as keys in a {@code SortedMap} or elements in a {@code SortedSet}.
  98  * See {@link Comparable}, {@link java.util.SortedMap SortedMap}, or
  99  * {@link java.util.SortedSet SortedSet} for more information.
 100  *
 101  * @author      Arthur van Hoff
 102  * @see     java.lang.StringBuilder
 103  * @see     java.lang.String
 104  * @since   1.0
 105  */
 106  public final class StringBuffer
 107     extends AbstractStringBuilder
 108     implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
 109 {
 110 
 111     /**
 112      * A cache of the last value returned by toString. Cleared
 113      * whenever the StringBuffer is modified.
 114      */
 115     private transient String toStringCache;
 116 
 117     /** use serialVersionUID from JDK 1.0.2 for interoperability */
 118     static final long serialVersionUID = 3388685877147921107L;
 119 
 120     /**
 121      * Constructs a string buffer with no characters in it and an
 122      * initial capacity of 16 characters.
 123      */
 124     @HotSpotIntrinsicCandidate
 125     public StringBuffer() {
 126         super(16);
 127     }
 128 
 129     /**
 130      * Constructs a string buffer with no characters in it and
 131      * the specified initial capacity.
 132      *
 133      * @param      capacity  the initial capacity.
 134      * @exception  NegativeArraySizeException  if the {@code capacity}
 135      *               argument is less than {@code 0}.
 136      */
 137     @HotSpotIntrinsicCandidate
 138     public StringBuffer(int capacity) {
 139         super(capacity);
 140     }
 141 
 142     /**
 143      * Constructs a string buffer initialized to the contents of the
 144      * specified string. The initial capacity of the string buffer is
 145      * {@code 16} plus the length of the string argument.
 146      *
 147      * @param   str   the initial contents of the buffer.
 148      */
 149     @HotSpotIntrinsicCandidate
 150     public StringBuffer(String str) {
 151         super(str.length() + 16);
 152         append(str);
 153     }
 154 
 155     /**
 156      * Constructs a string buffer that contains the same characters
 157      * as the specified {@code CharSequence}. The initial capacity of
 158      * the string buffer is {@code 16} plus the length of the
 159      * {@code CharSequence} argument.
 160      * <p>
 161      * If the length of the specified {@code CharSequence} is
 162      * less than or equal to zero, then an empty buffer of capacity
 163      * {@code 16} is returned.
 164      *
 165      * @param      seq   the sequence to copy.
 166      * @since 1.5
 167      */
 168     public StringBuffer(CharSequence seq) {
 169         this(seq.length() + 16);
 170         append(seq);
 171     }
 172 
 173     /**
 174      * Compares two {@code StringBuffer} instances lexicographically. This method
 175      * follows the same rules for lexicographical comparison as defined in the
 176      * {@linkplain java.lang.CharSequence#compare(java.lang.CharSequence,
 177      * java.lang.CharSequence)  CharSequence.compare(this, another)} method.
 178      *
 179      * <p>
 180      * For finer-grained, locale-sensitive String comparison, refer to
 181      * {@link java.text.Collator}.
 182      *
 183      * @implNote
 184      * This method synchronizes on {@code this}, the current object, but not
 185      * {@code StringBuffer another} with which {@code this StringBuffer} is compared.
 186      *
 187      * @param another the {@code StringBuffer} to be compared with
 188      *
 189      * @return  the value {@code 0} if this {@code StringBuffer} contains the same
 190      * character sequence as that of the argument {@code StringBuffer}; a negative integer
 191      * if this {@code StringBuffer} is lexicographically less than the
 192      * {@code StringBuffer} argument; or a positive integer if this {@code StringBuffer}
 193      * is lexicographically greater than the {@code StringBuffer} argument.
 194      *
 195      * @since 11
 196      */
 197     @Override
 198     public synchronized int compareTo(StringBuffer another) {
 199         return super.compareTo(another);
 200     }
 201 
 202     @Override
 203     public synchronized int length() {
 204         return count;
 205     }
 206 
 207     @Override
 208     public synchronized int capacity() {
 209         return super.capacity();
 210     }
 211 
 212 
 213     @Override
 214     public synchronized void ensureCapacity(int minimumCapacity) {
 215         super.ensureCapacity(minimumCapacity);
 216     }
 217 
 218     /**
 219      * @since      1.5
 220      */
 221     @Override
 222     public synchronized void trimToSize() {
 223         super.trimToSize();
 224     }
 225 
 226     /**
 227      * @throws IndexOutOfBoundsException {@inheritDoc}
 228      * @see        #length()
 229      */
 230     @Override
 231     public synchronized void setLength(int newLength) {
 232         toStringCache = null;
 233         super.setLength(newLength);
 234     }
 235 
 236     /**
 237      * @throws IndexOutOfBoundsException {@inheritDoc}
 238      * @see        #length()
 239      */
 240     @Override
 241     public synchronized char charAt(int index) {
 242         return super.charAt(index);
 243     }
 244 
 245     /**
 246      * @throws IndexOutOfBoundsException {@inheritDoc}
 247      * @since      1.5
 248      */
 249     @Override
 250     public synchronized int codePointAt(int index) {
 251         return super.codePointAt(index);
 252     }
 253 
 254     /**
 255      * @throws IndexOutOfBoundsException {@inheritDoc}
 256      * @since     1.5
 257      */
 258     @Override
 259     public synchronized int codePointBefore(int index) {
 260         return super.codePointBefore(index);
 261     }
 262 
 263     /**
 264      * @throws IndexOutOfBoundsException {@inheritDoc}
 265      * @since     1.5
 266      */
 267     @Override
 268     public synchronized int codePointCount(int beginIndex, int endIndex) {
 269         return super.codePointCount(beginIndex, endIndex);
 270     }
 271 
 272     /**
 273      * @throws IndexOutOfBoundsException {@inheritDoc}
 274      * @since     1.5
 275      */
 276     @Override
 277     public synchronized int offsetByCodePoints(int index, int codePointOffset) {
 278         return super.offsetByCodePoints(index, codePointOffset);
 279     }
 280 
 281     /**
 282      * @throws IndexOutOfBoundsException {@inheritDoc}
 283      */
 284     @Override
 285     public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
 286                                       int dstBegin)
 287     {
 288         super.getChars(srcBegin, srcEnd, dst, dstBegin);
 289     }
 290 
 291     /**
 292      * @throws IndexOutOfBoundsException {@inheritDoc}
 293      * @see        #length()
 294      */
 295     @Override
 296     public synchronized void setCharAt(int index, char ch) {
 297         toStringCache = null;
 298         super.setCharAt(index, ch);
 299     }
 300 
 301     @Override
 302     public synchronized StringBuffer append(Object obj) {
 303         toStringCache = null;
 304         super.append(String.valueOf(obj));
 305         return this;
 306     }
 307 
 308     @Override
 309     @HotSpotIntrinsicCandidate
 310     public synchronized StringBuffer append(String str) {
 311         toStringCache = null;
 312         super.append(str);
 313         return this;
 314     }
 315 
 316     /**
 317      * Appends the specified {@code StringBuffer} to this sequence.
 318      * <p>
 319      * The characters of the {@code StringBuffer} argument are appended,
 320      * in order, to the contents of this {@code StringBuffer}, increasing the
 321      * length of this {@code StringBuffer} by the length of the argument.
 322      * If {@code sb} is {@code null}, then the four characters
 323      * {@code "null"} are appended to this {@code StringBuffer}.
 324      * <p>
 325      * Let <i>n</i> be the length of the old character sequence, the one
 326      * contained in the {@code StringBuffer} just prior to execution of the
 327      * {@code append} method. Then the character at index <i>k</i> in
 328      * the new character sequence is equal to the character at index <i>k</i>
 329      * in the old character sequence, if <i>k</i> is less than <i>n</i>;
 330      * otherwise, it is equal to the character at index <i>k-n</i> in the
 331      * argument {@code sb}.
 332      * <p>
 333      * This method synchronizes on {@code this}, the destination
 334      * object, but does not synchronize on the source ({@code sb}).
 335      *
 336      * @param   sb   the {@code StringBuffer} to append.
 337      * @return  a reference to this object.
 338      * @since 1.4
 339      */
 340     public synchronized StringBuffer append(StringBuffer sb) {
 341         toStringCache = null;
 342         super.append(sb);
 343         return this;
 344     }
 345 
 346     /**
 347      * @since 1.8
 348      */
 349     @Override
 350     synchronized StringBuffer append(AbstractStringBuilder asb) {
 351         toStringCache = null;
 352         super.append(asb);
 353         return this;
 354     }
 355 
 356     /**
 357      * Appends the specified {@code CharSequence} to this
 358      * sequence.
 359      * <p>
 360      * The characters of the {@code CharSequence} argument are appended,
 361      * in order, increasing the length of this sequence by the length of the
 362      * argument.
 363      *
 364      * <p>The result of this method is exactly the same as if it were an
 365      * invocation of this.append(s, 0, s.length());
 366      *
 367      * <p>This method synchronizes on {@code this}, the destination
 368      * object, but does not synchronize on the source ({@code s}).
 369      *
 370      * <p>If {@code s} is {@code null}, then the four characters
 371      * {@code "null"} are appended.
 372      *
 373      * @param   s the {@code CharSequence} to append.
 374      * @return  a reference to this object.
 375      * @since 1.5
 376      */
 377     @Override
 378     public synchronized StringBuffer append(CharSequence s) {
 379         toStringCache = null;
 380         super.append(s);
 381         return this;
 382     }
 383 
 384     /**
 385      * @throws IndexOutOfBoundsException {@inheritDoc}
 386      * @since      1.5
 387      */
 388     @Override
 389     public synchronized StringBuffer append(CharSequence s, int start, int end)
 390     {
 391         toStringCache = null;
 392         super.append(s, start, end);
 393         return this;
 394     }
 395 
 396     @Override
 397     public synchronized StringBuffer append(char[] str) {
 398         toStringCache = null;
 399         super.append(str);
 400         return this;
 401     }
 402 
 403     /**
 404      * @throws IndexOutOfBoundsException {@inheritDoc}
 405      */
 406     @Override
 407     public synchronized StringBuffer append(char[] str, int offset, int len) {
 408         toStringCache = null;
 409         super.append(str, offset, len);
 410         return this;
 411     }
 412 
 413     @Override
 414     public synchronized StringBuffer append(boolean b) {
 415         toStringCache = null;
 416         super.append(b);
 417         return this;
 418     }
 419 
 420     @Override
 421     @HotSpotIntrinsicCandidate
 422     public synchronized StringBuffer append(char c) {
 423         toStringCache = null;
 424         super.append(c);
 425         return this;
 426     }
 427 
 428     @Override
 429     @HotSpotIntrinsicCandidate
 430     public synchronized StringBuffer append(int i) {
 431         toStringCache = null;
 432         super.append(i);
 433         return this;
 434     }
 435 
 436     /**
 437      * @since 1.5
 438      */
 439     @Override
 440     public synchronized StringBuffer appendCodePoint(int codePoint) {
 441         toStringCache = null;
 442         super.appendCodePoint(codePoint);
 443         return this;
 444     }
 445 
 446     @Override
 447     public synchronized StringBuffer append(long lng) {
 448         toStringCache = null;
 449         super.append(lng);
 450         return this;
 451     }
 452 
 453     @Override
 454     public synchronized StringBuffer append(float f) {
 455         toStringCache = null;
 456         super.append(f);
 457         return this;
 458     }
 459 
 460     @Override
 461     public synchronized StringBuffer append(double d) {
 462         toStringCache = null;
 463         super.append(d);
 464         return this;
 465     }
 466 
 467     /**
 468      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 469      * @since      1.2
 470      */
 471     @Override
 472     public synchronized StringBuffer delete(int start, int end) {
 473         toStringCache = null;
 474         super.delete(start, end);
 475         return this;
 476     }
 477 
 478     /**
 479      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 480      * @since      1.2
 481      */
 482     @Override
 483     public synchronized StringBuffer deleteCharAt(int index) {
 484         toStringCache = null;
 485         super.deleteCharAt(index);
 486         return this;
 487     }
 488 
 489     /**
 490      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 491      * @since      1.2
 492      */
 493     @Override
 494     public synchronized StringBuffer replace(int start, int end, String str) {
 495         toStringCache = null;
 496         super.replace(start, end, str);
 497         return this;
 498     }
 499 
 500     /**
 501      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 502      * @since      1.2
 503      */
 504     @Override
 505     public synchronized String substring(int start) {
 506         return substring(start, count);
 507     }
 508 
 509     /**
 510      * @throws IndexOutOfBoundsException {@inheritDoc}
 511      * @since      1.4
 512      */
 513     @Override
 514     public synchronized CharSequence subSequence(int start, int end) {
 515         return super.substring(start, end);
 516     }
 517 
 518     /**
 519      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 520      * @since      1.2
 521      */
 522     @Override
 523     public synchronized String substring(int start, int end) {
 524         return super.substring(start, end);
 525     }
 526 
 527     /**
 528      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 529      * @since      1.2
 530      */
 531     @Override
 532     public synchronized StringBuffer insert(int index, char[] str, int offset,
 533                                             int len)
 534     {
 535         toStringCache = null;
 536         super.insert(index, str, offset, len);
 537         return this;
 538     }
 539 
 540     /**
 541      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 542      */
 543     @Override
 544     public synchronized StringBuffer insert(int offset, Object obj) {
 545         toStringCache = null;
 546         super.insert(offset, String.valueOf(obj));
 547         return this;
 548     }
 549 
 550     /**
 551      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 552      */
 553     @Override
 554     public synchronized StringBuffer insert(int offset, String str) {
 555         toStringCache = null;
 556         super.insert(offset, str);
 557         return this;
 558     }
 559 
 560     /**
 561      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 562      */
 563     @Override
 564     public synchronized StringBuffer insert(int offset, char[] str) {
 565         toStringCache = null;
 566         super.insert(offset, str);
 567         return this;
 568     }
 569 
 570     /**
 571      * @throws IndexOutOfBoundsException {@inheritDoc}
 572      * @since      1.5
 573      */
 574     @Override
 575     public StringBuffer insert(int dstOffset, CharSequence s) {
 576         // Note, synchronization achieved via invocations of other StringBuffer methods
 577         // after narrowing of s to specific type
 578         // Ditto for toStringCache clearing
 579         super.insert(dstOffset, s);
 580         return this;
 581     }
 582 
 583     /**
 584      * @throws IndexOutOfBoundsException {@inheritDoc}
 585      * @since      1.5
 586      */
 587     @Override
 588     public synchronized StringBuffer insert(int dstOffset, CharSequence s,
 589             int start, int end)
 590     {
 591         toStringCache = null;
 592         super.insert(dstOffset, s, start, end);
 593         return this;
 594     }
 595 
 596     /**
 597      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 598      */
 599     @Override
 600     public  StringBuffer insert(int offset, boolean b) {
 601         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 602         // after conversion of b to String by super class method
 603         // Ditto for toStringCache clearing
 604         super.insert(offset, b);
 605         return this;
 606     }
 607 
 608     /**
 609      * @throws IndexOutOfBoundsException {@inheritDoc}
 610      */
 611     @Override
 612     public synchronized StringBuffer insert(int offset, char c) {
 613         toStringCache = null;
 614         super.insert(offset, c);
 615         return this;
 616     }
 617 
 618     /**
 619      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 620      */
 621     @Override
 622     public StringBuffer insert(int offset, int i) {
 623         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 624         // after conversion of i to String by super class method
 625         // Ditto for toStringCache clearing
 626         super.insert(offset, i);
 627         return this;
 628     }
 629 
 630     /**
 631      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 632      */
 633     @Override
 634     public StringBuffer insert(int offset, long l) {
 635         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 636         // after conversion of l to String by super class method
 637         // Ditto for toStringCache clearing
 638         super.insert(offset, l);
 639         return this;
 640     }
 641 
 642     /**
 643      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 644      */
 645     @Override
 646     public StringBuffer insert(int offset, float f) {
 647         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 648         // after conversion of f to String by super class method
 649         // Ditto for toStringCache clearing
 650         super.insert(offset, f);
 651         return this;
 652     }
 653 
 654     /**
 655      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 656      */
 657     @Override
 658     public StringBuffer insert(int offset, double d) {
 659         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 660         // after conversion of d to String by super class method
 661         // Ditto for toStringCache clearing
 662         super.insert(offset, d);
 663         return this;
 664     }
 665 
 666     /**
 667      * @since      1.4
 668      */
 669     @Override
 670     public int indexOf(String str) {
 671         // Note, synchronization achieved via invocations of other StringBuffer methods
 672         return super.indexOf(str);
 673     }
 674 
 675     /**
 676      * @since      1.4
 677      */
 678     @Override
 679     public synchronized int indexOf(String str, int fromIndex) {
 680         return super.indexOf(str, fromIndex);
 681     }
 682 
 683     /**
 684      * @since      1.4
 685      */
 686     @Override
 687     public int lastIndexOf(String str) {
 688         // Note, synchronization achieved via invocations of other StringBuffer methods
 689         return lastIndexOf(str, count);
 690     }
 691 
 692     /**
 693      * @since      1.4
 694      */
 695     @Override
 696     public synchronized int lastIndexOf(String str, int fromIndex) {
 697         return super.lastIndexOf(str, fromIndex);
 698     }
 699 
 700     /**
 701      * @since   1.0.2
 702      */
 703     @Override
 704     public synchronized StringBuffer reverse() {
 705         toStringCache = null;
 706         super.reverse();
 707         return this;
 708     }
 709 
 710     @Override
 711     @HotSpotIntrinsicCandidate
 712     public synchronized String toString() {
 713         if (toStringCache == null) {
 714             return toStringCache =
 715                     isLatin1() ? StringLatin1.newString(value, 0, count)
 716                                : StringUTF16.newString(value, 0, count);
 717         }
 718         return new String(toStringCache);
 719     }
 720 
 721     /**
 722      * Serializable fields for StringBuffer.
 723      *
 724      * @serialField value  char[]
 725      *              The backing character array of this StringBuffer.
 726      * @serialField count int
 727      *              The number of characters in this StringBuffer.
 728      * @serialField shared  boolean
 729      *              A flag indicating whether the backing array is shared.
 730      *              The value is ignored upon deserialization.
 731      */
 732     private static final java.io.ObjectStreamField[] serialPersistentFields =
 733     {
 734         new java.io.ObjectStreamField("value", char[].class),
 735         new java.io.ObjectStreamField("count", Integer.TYPE),
 736         new java.io.ObjectStreamField("shared", Boolean.TYPE),
 737     };
 738 
 739     /**
 740      * readObject is called to restore the state of the StringBuffer from
 741      * a stream.
 742      */
 743     private synchronized void writeObject(java.io.ObjectOutputStream s)
 744         throws java.io.IOException {
 745         java.io.ObjectOutputStream.PutField fields = s.putFields();
 746         char[] val = new char[capacity()];
 747         if (isLatin1()) {
 748             StringLatin1.getChars(value, 0, count, val, 0);
 749         } else {
 750             StringUTF16.getChars(value, 0, count, val, 0);
 751         }
 752         fields.put("value", val);
 753         fields.put("count", count);
 754         fields.put("shared", false);
 755         s.writeFields();
 756     }
 757 
 758     /**
 759      * readObject is called to restore the state of the StringBuffer from
 760      * a stream.
 761      */
 762     private void readObject(java.io.ObjectInputStream s)
 763         throws java.io.IOException, ClassNotFoundException {
 764         java.io.ObjectInputStream.GetField fields = s.readFields();
 765         char[] val = (char[])fields.get("value", null);
 766         initBytes(val, 0, val.length);
 767         count = fields.get("count", 0);
 768     }
 769 
 770     synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
 771         super.getBytes(dst, dstBegin, coder);
 772     }
 773 }