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