1 /*
   2  * Copyright (c) 1994, 2019, 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      * @throws     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);
 152     }
 153 
 154     /**
 155      * Constructs a string buffer that contains the same characters
 156      * as the specified {@code CharSequence}. The initial capacity of
 157      * the string buffer is {@code 16} plus the length of the
 158      * {@code CharSequence} argument.
 159      *
 160      * @param      seq   the sequence to copy.
 161      * @since 1.5
 162      */
 163     public StringBuffer(CharSequence seq) {
 164         super(seq);
 165     }
 166 
 167     /**
 168      * Compares two {@code StringBuffer} instances lexicographically. This method
 169      * follows the same rules for lexicographical comparison as defined in the
 170      * {@linkplain java.lang.CharSequence#compare(java.lang.CharSequence,
 171      * java.lang.CharSequence)  CharSequence.compare(this, another)} method.
 172      *
 173      * <p>
 174      * For finer-grained, locale-sensitive String comparison, refer to
 175      * {@link java.text.Collator}.
 176      *
 177      * @implNote
 178      * This method synchronizes on {@code this}, the current object, but not
 179      * {@code StringBuffer another} with which {@code this StringBuffer} is compared.
 180      *
 181      * @param another the {@code StringBuffer} to be compared with
 182      *
 183      * @return  the value {@code 0} if this {@code StringBuffer} contains the same
 184      * character sequence as that of the argument {@code StringBuffer}; a negative integer
 185      * if this {@code StringBuffer} is lexicographically less than the
 186      * {@code StringBuffer} argument; or a positive integer if this {@code StringBuffer}
 187      * is lexicographically greater than the {@code StringBuffer} argument.
 188      *
 189      * @since 11
 190      */
 191     @Override
 192     public synchronized int compareTo(StringBuffer another) {
 193         return super.compareTo(another);
 194     }
 195 
 196     @Override
 197     public synchronized int length() {
 198         return count;
 199     }
 200 
 201     @Override
 202     public synchronized int capacity() {
 203         return super.capacity();
 204     }
 205 
 206 
 207     @Override
 208     public synchronized void ensureCapacity(int minimumCapacity) {
 209         super.ensureCapacity(minimumCapacity);
 210     }
 211 
 212     /**
 213      * @since      1.5
 214      */
 215     @Override
 216     public synchronized void trimToSize() {
 217         super.trimToSize();
 218     }
 219 
 220     /**
 221      * @throws IndexOutOfBoundsException {@inheritDoc}
 222      * @see        #length()
 223      */
 224     @Override
 225     public synchronized void setLength(int newLength) {
 226         toStringCache = null;
 227         super.setLength(newLength);
 228     }
 229 
 230     /**
 231      * @throws IndexOutOfBoundsException {@inheritDoc}
 232      * @see        #length()
 233      */
 234     @Override
 235     public synchronized char charAt(int index) {
 236         return super.charAt(index);
 237     }
 238 
 239     /**
 240      * @throws IndexOutOfBoundsException {@inheritDoc}
 241      * @since      1.5
 242      */
 243     @Override
 244     public synchronized int codePointAt(int index) {
 245         return super.codePointAt(index);
 246     }
 247 
 248     /**
 249      * @throws IndexOutOfBoundsException {@inheritDoc}
 250      * @since     1.5
 251      */
 252     @Override
 253     public synchronized int codePointBefore(int index) {
 254         return super.codePointBefore(index);
 255     }
 256 
 257     /**
 258      * @throws IndexOutOfBoundsException {@inheritDoc}
 259      * @since     1.5
 260      */
 261     @Override
 262     public synchronized int codePointCount(int beginIndex, int endIndex) {
 263         return super.codePointCount(beginIndex, endIndex);
 264     }
 265 
 266     /**
 267      * @throws IndexOutOfBoundsException {@inheritDoc}
 268      * @since     1.5
 269      */
 270     @Override
 271     public synchronized int offsetByCodePoints(int index, int codePointOffset) {
 272         return super.offsetByCodePoints(index, codePointOffset);
 273     }
 274 
 275     /**
 276      * @throws IndexOutOfBoundsException {@inheritDoc}
 277      */
 278     @Override
 279     public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
 280                                       int dstBegin)
 281     {
 282         super.getChars(srcBegin, srcEnd, dst, dstBegin);
 283     }
 284 
 285     /**
 286      * @throws IndexOutOfBoundsException {@inheritDoc}
 287      * @see        #length()
 288      */
 289     @Override
 290     public synchronized void setCharAt(int index, char ch) {
 291         toStringCache = null;
 292         super.setCharAt(index, ch);
 293     }
 294 
 295     @Override
 296     public synchronized StringBuffer append(Object obj) {
 297         toStringCache = null;
 298         super.append(String.valueOf(obj));
 299         return this;
 300     }
 301 
 302     @Override
 303     @HotSpotIntrinsicCandidate
 304     public synchronized StringBuffer append(String str) {
 305         toStringCache = null;
 306         super.append(str);
 307         return this;
 308     }
 309 
 310     /**
 311      * Appends the specified {@code StringBuffer} to this sequence.
 312      * <p>
 313      * The characters of the {@code StringBuffer} argument are appended,
 314      * in order, to the contents of this {@code StringBuffer}, increasing the
 315      * length of this {@code StringBuffer} by the length of the argument.
 316      * If {@code sb} is {@code null}, then the four characters
 317      * {@code "null"} are appended to this {@code StringBuffer}.
 318      * <p>
 319      * Let <i>n</i> be the length of the old character sequence, the one
 320      * contained in the {@code StringBuffer} just prior to execution of the
 321      * {@code append} method. Then the character at index <i>k</i> in
 322      * the new character sequence is equal to the character at index <i>k</i>
 323      * in the old character sequence, if <i>k</i> is less than <i>n</i>;
 324      * otherwise, it is equal to the character at index <i>k-n</i> in the
 325      * argument {@code sb}.
 326      * <p>
 327      * This method synchronizes on {@code this}, the destination
 328      * object, but does not synchronize on the source ({@code sb}).
 329      *
 330      * @param   sb   the {@code StringBuffer} to append.
 331      * @return  a reference to this object.
 332      * @since 1.4
 333      */
 334     public synchronized StringBuffer append(StringBuffer sb) {
 335         toStringCache = null;
 336         super.append(sb);
 337         return this;
 338     }
 339 
 340     /**
 341      * @since 1.8
 342      */
 343     @Override
 344     synchronized StringBuffer append(AbstractStringBuilder asb) {
 345         toStringCache = null;
 346         super.append(asb);
 347         return this;
 348     }
 349 
 350     /**
 351      * Appends the specified {@code CharSequence} to this
 352      * sequence.
 353      * <p>
 354      * The characters of the {@code CharSequence} argument are appended,
 355      * in order, increasing the length of this sequence by the length of the
 356      * argument.
 357      *
 358      * <p>The result of this method is exactly the same as if it were an
 359      * invocation of this.append(s, 0, s.length());
 360      *
 361      * <p>This method synchronizes on {@code this}, the destination
 362      * object, but does not synchronize on the source ({@code s}).
 363      *
 364      * <p>If {@code s} is {@code null}, then the four characters
 365      * {@code "null"} are appended.
 366      *
 367      * @param   s the {@code CharSequence} to append.
 368      * @return  a reference to this object.
 369      * @since 1.5
 370      */
 371     @Override
 372     public synchronized StringBuffer append(CharSequence s) {
 373         toStringCache = null;
 374         super.append(s);
 375         return this;
 376     }
 377 
 378     /**
 379      * @throws IndexOutOfBoundsException {@inheritDoc}
 380      * @since      1.5
 381      */
 382     @Override
 383     public synchronized StringBuffer append(CharSequence s, int start, int end)
 384     {
 385         toStringCache = null;
 386         super.append(s, start, end);
 387         return this;
 388     }
 389 
 390     @Override
 391     public synchronized StringBuffer append(char[] str) {
 392         toStringCache = null;
 393         super.append(str);
 394         return this;
 395     }
 396 
 397     /**
 398      * @throws IndexOutOfBoundsException {@inheritDoc}
 399      */
 400     @Override
 401     public synchronized StringBuffer append(char[] str, int offset, int len) {
 402         toStringCache = null;
 403         super.append(str, offset, len);
 404         return this;
 405     }
 406 
 407     @Override
 408     public synchronized StringBuffer append(boolean b) {
 409         toStringCache = null;
 410         super.append(b);
 411         return this;
 412     }
 413 
 414     @Override
 415     @HotSpotIntrinsicCandidate
 416     public synchronized StringBuffer append(char c) {
 417         toStringCache = null;
 418         super.append(c);
 419         return this;
 420     }
 421 
 422     @Override
 423     @HotSpotIntrinsicCandidate
 424     public synchronized StringBuffer append(int i) {
 425         toStringCache = null;
 426         super.append(i);
 427         return this;
 428     }
 429 
 430     /**
 431      * @since 1.5
 432      */
 433     @Override
 434     public synchronized StringBuffer appendCodePoint(int codePoint) {
 435         toStringCache = null;
 436         super.appendCodePoint(codePoint);
 437         return this;
 438     }
 439 
 440     @Override
 441     public synchronized StringBuffer append(long lng) {
 442         toStringCache = null;
 443         super.append(lng);
 444         return this;
 445     }
 446 
 447     @Override
 448     public synchronized StringBuffer append(float f) {
 449         toStringCache = null;
 450         super.append(f);
 451         return this;
 452     }
 453 
 454     @Override
 455     public synchronized StringBuffer append(double d) {
 456         toStringCache = null;
 457         super.append(d);
 458         return this;
 459     }
 460 
 461     /**
 462      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 463      * @since      1.2
 464      */
 465     @Override
 466     public synchronized StringBuffer delete(int start, int end) {
 467         toStringCache = null;
 468         super.delete(start, end);
 469         return this;
 470     }
 471 
 472     /**
 473      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 474      * @since      1.2
 475      */
 476     @Override
 477     public synchronized StringBuffer deleteCharAt(int index) {
 478         toStringCache = null;
 479         super.deleteCharAt(index);
 480         return this;
 481     }
 482 
 483     /**
 484      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 485      * @since      1.2
 486      */
 487     @Override
 488     public synchronized StringBuffer replace(int start, int end, String str) {
 489         toStringCache = null;
 490         super.replace(start, end, str);
 491         return this;
 492     }
 493 
 494     /**
 495      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 496      * @since      1.2
 497      */
 498     @Override
 499     public synchronized String substring(int start) {
 500         return substring(start, count);
 501     }
 502 
 503     /**
 504      * @throws IndexOutOfBoundsException {@inheritDoc}
 505      * @since      1.4
 506      */
 507     @Override
 508     public synchronized CharSequence subSequence(int start, int end) {
 509         return super.substring(start, end);
 510     }
 511 
 512     /**
 513      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 514      * @since      1.2
 515      */
 516     @Override
 517     public synchronized String substring(int start, int end) {
 518         return super.substring(start, end);
 519     }
 520 
 521     /**
 522      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 523      * @since      1.2
 524      */
 525     @Override
 526     public synchronized StringBuffer insert(int index, char[] str, int offset,
 527                                             int len)
 528     {
 529         toStringCache = null;
 530         super.insert(index, str, offset, len);
 531         return this;
 532     }
 533 
 534     /**
 535      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 536      */
 537     @Override
 538     public synchronized StringBuffer insert(int offset, Object obj) {
 539         toStringCache = null;
 540         super.insert(offset, String.valueOf(obj));
 541         return this;
 542     }
 543 
 544     /**
 545      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 546      */
 547     @Override
 548     public synchronized StringBuffer insert(int offset, String str) {
 549         toStringCache = null;
 550         super.insert(offset, str);
 551         return this;
 552     }
 553 
 554     /**
 555      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 556      */
 557     @Override
 558     public synchronized StringBuffer insert(int offset, char[] str) {
 559         toStringCache = null;
 560         super.insert(offset, str);
 561         return this;
 562     }
 563 
 564     /**
 565      * @throws IndexOutOfBoundsException {@inheritDoc}
 566      * @since      1.5
 567      */
 568     @Override
 569     public StringBuffer insert(int dstOffset, CharSequence s) {
 570         // Note, synchronization achieved via invocations of other StringBuffer methods
 571         // after narrowing of s to specific type
 572         // Ditto for toStringCache clearing
 573         super.insert(dstOffset, s);
 574         return this;
 575     }
 576 
 577     /**
 578      * @throws IndexOutOfBoundsException {@inheritDoc}
 579      * @since      1.5
 580      */
 581     @Override
 582     public synchronized StringBuffer insert(int dstOffset, CharSequence s,
 583             int start, int end)
 584     {
 585         toStringCache = null;
 586         super.insert(dstOffset, s, start, end);
 587         return this;
 588     }
 589 
 590     /**
 591      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 592      */
 593     @Override
 594     public  StringBuffer insert(int offset, boolean b) {
 595         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 596         // after conversion of b to String by super class method
 597         // Ditto for toStringCache clearing
 598         super.insert(offset, b);
 599         return this;
 600     }
 601 
 602     /**
 603      * @throws IndexOutOfBoundsException {@inheritDoc}
 604      */
 605     @Override
 606     public synchronized StringBuffer insert(int offset, char c) {
 607         toStringCache = null;
 608         super.insert(offset, c);
 609         return this;
 610     }
 611 
 612     /**
 613      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 614      */
 615     @Override
 616     public StringBuffer insert(int offset, int i) {
 617         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 618         // after conversion of i to String by super class method
 619         // Ditto for toStringCache clearing
 620         super.insert(offset, i);
 621         return this;
 622     }
 623 
 624     /**
 625      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 626      */
 627     @Override
 628     public StringBuffer insert(int offset, long l) {
 629         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 630         // after conversion of l to String by super class method
 631         // Ditto for toStringCache clearing
 632         super.insert(offset, l);
 633         return this;
 634     }
 635 
 636     /**
 637      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 638      */
 639     @Override
 640     public StringBuffer insert(int offset, float f) {
 641         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 642         // after conversion of f to String by super class method
 643         // Ditto for toStringCache clearing
 644         super.insert(offset, f);
 645         return this;
 646     }
 647 
 648     /**
 649      * @throws StringIndexOutOfBoundsException {@inheritDoc}
 650      */
 651     @Override
 652     public StringBuffer insert(int offset, double d) {
 653         // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
 654         // after conversion of d to String by super class method
 655         // Ditto for toStringCache clearing
 656         super.insert(offset, d);
 657         return this;
 658     }
 659 
 660     /**
 661      * @since      1.4
 662      */
 663     @Override
 664     public int indexOf(String str) {
 665         // Note, synchronization achieved via invocations of other StringBuffer methods
 666         return super.indexOf(str);
 667     }
 668 
 669     /**
 670      * @since      1.4
 671      */
 672     @Override
 673     public synchronized int indexOf(String str, int fromIndex) {
 674         return super.indexOf(str, fromIndex);
 675     }
 676 
 677     /**
 678      * @since      1.4
 679      */
 680     @Override
 681     public int lastIndexOf(String str) {
 682         // Note, synchronization achieved via invocations of other StringBuffer methods
 683         return lastIndexOf(str, count);
 684     }
 685 
 686     /**
 687      * @since      1.4
 688      */
 689     @Override
 690     public synchronized int lastIndexOf(String str, int fromIndex) {
 691         return super.lastIndexOf(str, fromIndex);
 692     }
 693 
 694     /**
 695      * @since   1.0.2
 696      */
 697     @Override
 698     public synchronized StringBuffer reverse() {
 699         toStringCache = null;
 700         super.reverse();
 701         return this;
 702     }
 703 
 704     @Override
 705     @HotSpotIntrinsicCandidate
 706     public synchronized String toString() {
 707         if (toStringCache == null) {
 708             return toStringCache =
 709                     isLatin1() ? StringLatin1.newString(value, 0, count)
 710                                : StringUTF16.newString(value, 0, count);
 711         }
 712         return new String(toStringCache);
 713     }
 714 
 715     /**
 716      * Serializable fields for StringBuffer.
 717      *
 718      * @serialField value  char[]
 719      *              The backing character array of this StringBuffer.
 720      * @serialField count int
 721      *              The number of characters in this StringBuffer.
 722      * @serialField shared  boolean
 723      *              A flag indicating whether the backing array is shared.
 724      *              The value is ignored upon deserialization.
 725      */
 726     private static final java.io.ObjectStreamField[] serialPersistentFields =
 727     {
 728         new java.io.ObjectStreamField("value", char[].class),
 729         new java.io.ObjectStreamField("count", Integer.TYPE),
 730         new java.io.ObjectStreamField("shared", Boolean.TYPE),
 731     };
 732 
 733     /**
 734      * readObject is called to restore the state of the StringBuffer from
 735      * a stream.
 736      */
 737     private synchronized void writeObject(java.io.ObjectOutputStream s)
 738         throws java.io.IOException {
 739         java.io.ObjectOutputStream.PutField fields = s.putFields();
 740         char[] val = new char[capacity()];
 741         if (isLatin1()) {
 742             StringLatin1.getChars(value, 0, count, val, 0);
 743         } else {
 744             StringUTF16.getChars(value, 0, count, val, 0);
 745         }
 746         fields.put("value", val);
 747         fields.put("count", count);
 748         fields.put("shared", false);
 749         s.writeFields();
 750     }
 751 
 752     /**
 753      * readObject is called to restore the state of the StringBuffer from
 754      * a stream.
 755      */
 756     private void readObject(java.io.ObjectInputStream s)
 757         throws java.io.IOException, ClassNotFoundException {
 758         java.io.ObjectInputStream.GetField fields = s.readFields();
 759         char[] val = (char[])fields.get("value", null);
 760         initBytes(val, 0, val.length);
 761         count = fields.get("count", 0);
 762     }
 763 
 764     synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
 765         super.getBytes(dst, dstBegin, coder);
 766     }
 767 }