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