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