1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.lang;
19
20import java.io.IOException;
21import java.io.ObjectInputStream;
22import java.io.ObjectOutputStream;
23import java.io.Serializable;
24
25/**
26 * A modifiable {@link CharSequence sequence of characters} for use in creating
27 * strings. This class is intended as a direct replacement of
28 * {@link StringBuffer} for non-concurrent use; unlike {@code StringBuffer} this
29 * class is not synchronized.
30 *
31 * <p>For particularly complex string-building needs, consider {@link java.util.Formatter}.
32 *
33 * <p>The majority of the modification methods on this class return {@code
34 * this} so that method calls can be chained together. For example:
35 * {@code new StringBuilder("a").append("b").append("c").toString()}.
36 *
37 * @see CharSequence
38 * @see Appendable
39 * @see StringBuffer
40 * @see String
41 * @see String.format
42 * @since 1.5
43 */
44public final class StringBuilder extends AbstractStringBuilder implements
45        Appendable, CharSequence, Serializable {
46
47    private static final long serialVersionUID = 4383685877147921099L;
48
49    /**
50     * Constructs an instance with an initial capacity of {@code 16}.
51     *
52     * @see #capacity()
53     */
54    public StringBuilder() {
55        super();
56    }
57
58    /**
59     * Constructs an instance with the specified capacity.
60     *
61     * @param capacity
62     *            the initial capacity to use.
63     * @throws NegativeArraySizeException
64     *             if the specified {@code capacity} is negative.
65     * @see #capacity()
66     */
67    public StringBuilder(int capacity) {
68        super(capacity);
69    }
70
71    /**
72     * Constructs an instance that's initialized with the contents of the
73     * specified {@code CharSequence}. The capacity of the new builder will be
74     * the length of the {@code CharSequence} plus 16.
75     *
76     * @param seq
77     *            the {@code CharSequence} to copy into the builder.
78     * @throws NullPointerException
79     *            if {@code seq} is {@code null}.
80     */
81    public StringBuilder(CharSequence seq) {
82        super(seq.toString());
83    }
84
85    /**
86     * Constructs an instance that's initialized with the contents of the
87     * specified {@code String}. The capacity of the new builder will be the
88     * length of the {@code String} plus 16.
89     *
90     * @param str
91     *            the {@code String} to copy into the builder.
92     * @throws NullPointerException
93     *            if {@code str} is {@code null}.
94     */
95    public StringBuilder(String str) {
96        super(str);
97    }
98
99    /**
100     * Appends the string representation of the specified {@code boolean} value.
101     * The {@code boolean} value is converted to a String according to the rule
102     * defined by {@link String#valueOf(boolean)}.
103     *
104     * @param b
105     *            the {@code boolean} value to append.
106     * @return this builder.
107     * @see String#valueOf(boolean)
108     */
109    public StringBuilder append(boolean b) {
110        append0(b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
111        return this;
112    }
113
114    /**
115     * Appends the string representation of the specified {@code char} value.
116     * The {@code char} value is converted to a string according to the rule
117     * defined by {@link String#valueOf(char)}.
118     *
119     * @param c
120     *            the {@code char} value to append.
121     * @return this builder.
122     * @see String#valueOf(char)
123     */
124    public StringBuilder append(char c) {
125        append0(c);
126        return this;
127    }
128
129    /**
130     * Appends the string representation of the specified {@code int} value. The
131     * {@code int} value is converted to a string according to the rule defined
132     * by {@link String#valueOf(int)}.
133     *
134     * @param i
135     *            the {@code int} value to append.
136     * @return this builder.
137     * @see String#valueOf(int)
138     */
139    public StringBuilder append(int i) {
140        append0(Integer.toString(i));
141        return this;
142    }
143
144    /**
145     * Appends the string representation of the specified {@code long} value.
146     * The {@code long} value is converted to a string according to the rule
147     * defined by {@link String#valueOf(long)}.
148     *
149     * @param lng
150     *            the {@code long} value.
151     * @return this builder.
152     * @see String#valueOf(long)
153     */
154    public StringBuilder append(long lng) {
155        append0(Long.toString(lng));
156        return this;
157    }
158
159    /**
160     * Appends the string representation of the specified {@code float} value.
161     * The {@code float} value is converted to a string according to the rule
162     * defined by {@link String#valueOf(float)}.
163     *
164     * @param f
165     *            the {@code float} value to append.
166     * @return this builder.
167     * @see String#valueOf(float)
168     */
169    public StringBuilder append(float f) {
170        append0(Float.toString(f));
171        return this;
172    }
173
174    /**
175     * Appends the string representation of the specified {@code double} value.
176     * The {@code double} value is converted to a string according to the rule
177     * defined by {@link String#valueOf(double)}.
178     *
179     * @param d
180     *            the {@code double} value to append.
181     * @return this builder.
182     * @see String#valueOf(double)
183     */
184    public StringBuilder append(double d) {
185        append0(Double.toString(d));
186        return this;
187    }
188
189    /**
190     * Appends the string representation of the specified {@code Object}.
191     * The {@code Object} value is converted to a string according to the rule
192     * defined by {@link String#valueOf(Object)}.
193     *
194     * @param obj
195     *            the {@code Object} to append.
196     * @return this builder.
197     * @see String#valueOf(Object)
198     */
199    public StringBuilder append(Object obj) {
200        if (obj == null) {
201            appendNull();
202        } else {
203            append0(obj.toString());
204        }
205        return this;
206    }
207
208    /**
209     * Appends the contents of the specified string. If the string is {@code
210     * null}, then the string {@code "null"} is appended.
211     *
212     * @param str
213     *            the string to append.
214     * @return this builder.
215     */
216    public StringBuilder append(String str) {
217        append0(str);
218        return this;
219    }
220
221    /**
222     * Appends the contents of the specified {@code StringBuffer}. If the
223     * StringBuffer is {@code null}, then the string {@code "null"} is
224     * appended.
225     *
226     * @param sb
227     *            the {@code StringBuffer} to append.
228     * @return this builder.
229     */
230    public StringBuilder append(StringBuffer sb) {
231        if (sb == null) {
232            appendNull();
233        } else {
234            append0(sb.getValue(), 0, sb.length());
235        }
236        return this;
237    }
238
239    /**
240     * Appends the string representation of the specified {@code char[]}.
241     * The {@code char[]} is converted to a string according to the rule
242     * defined by {@link String#valueOf(char[])}.
243     *
244     * @param ch
245     *            the {@code char[]} to append..
246     * @return this builder.
247     * @see String#valueOf(char[])
248     */
249    public StringBuilder append(char[] ch) {
250        append0(ch);
251        return this;
252    }
253
254    /**
255     * Appends the string representation of the specified subset of the {@code
256     * char[]}. The {@code char[]} value is converted to a String according to
257     * the rule defined by {@link String#valueOf(char[],int,int)}.
258     *
259     * @param str
260     *            the {@code char[]} to append.
261     * @param offset
262     *            the inclusive offset index.
263     * @param len
264     *            the number of characters.
265     * @return this builder.
266     * @throws ArrayIndexOutOfBoundsException
267     *             if {@code offset} and {@code len} do not specify a valid
268     *             subsequence.
269     * @see String#valueOf(char[],int,int)
270     */
271    public StringBuilder append(char[] str, int offset, int len) {
272        append0(str, offset, len);
273        return this;
274    }
275
276    /**
277     * Appends the string representation of the specified {@code CharSequence}.
278     * If the {@code CharSequence} is {@code null}, then the string {@code
279     * "null"} is appended.
280     *
281     * @param csq
282     *            the {@code CharSequence} to append.
283     * @return this builder.
284     */
285    public StringBuilder append(CharSequence csq) {
286        if (csq == null) {
287            appendNull();
288        } else {
289            append0(csq.toString());
290        }
291        return this;
292    }
293
294    /**
295     * Appends the string representation of the specified subsequence of the
296     * {@code CharSequence}. If the {@code CharSequence} is {@code null}, then
297     * the string {@code "null"} is used to extract the subsequence from.
298     *
299     * @param csq
300     *            the {@code CharSequence} to append.
301     * @param start
302     *            the beginning index.
303     * @param end
304     *            the ending index.
305     * @return this builder.
306     * @throws IndexOutOfBoundsException
307     *             if {@code start} or {@code end} are negative, {@code start}
308     *             is greater than {@code end} or {@code end} is greater than
309     *             the length of {@code csq}.
310     */
311    public StringBuilder append(CharSequence csq, int start, int end) {
312        append0(csq, start, end);
313        return this;
314    }
315
316    /**
317     * Appends the encoded Unicode code point. The code point is converted to a
318     * {@code char[]} as defined by {@link Character#toChars(int)}.
319     *
320     * @param codePoint
321     *            the Unicode code point to encode and append.
322     * @return this builder.
323     * @see Character#toChars(int)
324     */
325    public StringBuilder appendCodePoint(int codePoint) {
326        append0(Character.toChars(codePoint));
327        return this;
328    }
329
330    /**
331     * Deletes a sequence of characters specified by {@code start} and {@code
332     * end}. Shifts any remaining characters to the left.
333     *
334     * @param start
335     *            the inclusive start index.
336     * @param end
337     *            the exclusive end index.
338     * @return this builder.
339     * @throws StringIndexOutOfBoundsException
340     *             if {@code start} is less than zero, greater than the current
341     *             length or greater than {@code end}.
342     */
343    public StringBuilder delete(int start, int end) {
344        delete0(start, end);
345        return this;
346    }
347
348    /**
349     * Deletes the character at the specified index. shifts any remaining
350     * characters to the left.
351     *
352     * @param index
353     *            the index of the character to delete.
354     * @return this builder.
355     * @throws StringIndexOutOfBoundsException
356     *             if {@code index} is less than zero or is greater than or
357     *             equal to the current length.
358     */
359    public StringBuilder deleteCharAt(int index) {
360        deleteCharAt0(index);
361        return this;
362    }
363
364    /**
365     * Inserts the string representation of the specified {@code boolean} value
366     * at the specified {@code offset}. The {@code boolean} value is converted
367     * to a string according to the rule defined by
368     * {@link String#valueOf(boolean)}.
369     *
370     * @param offset
371     *            the index to insert at.
372     * @param b
373     *            the {@code boolean} value to insert.
374     * @return this builder.
375     * @throws StringIndexOutOfBoundsException
376     *             if {@code offset} is negative or greater than the current
377     *             {@code length}.
378     * @see String#valueOf(boolean)
379     */
380    public StringBuilder insert(int offset, boolean b) {
381        insert0(offset, b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
382        return this;
383    }
384
385    /**
386     * Inserts the string representation of the specified {@code char} value at
387     * the specified {@code offset}. The {@code char} value is converted to a
388     * string according to the rule defined by {@link String#valueOf(char)}.
389     *
390     * @param offset
391     *            the index to insert at.
392     * @param c
393     *            the {@code char} value to insert.
394     * @return this builder.
395     * @throws IndexOutOfBoundsException
396     *             if {@code offset} is negative or greater than the current
397     *             {@code length()}.
398     * @see String#valueOf(char)
399     */
400    public StringBuilder insert(int offset, char c) {
401        insert0(offset, c);
402        return this;
403    }
404
405    /**
406     * Inserts the string representation of the specified {@code int} value at
407     * the specified {@code offset}. The {@code int} value is converted to a
408     * String according to the rule defined by {@link String#valueOf(int)}.
409     *
410     * @param offset
411     *            the index to insert at.
412     * @param i
413     *            the {@code int} value to insert.
414     * @return this builder.
415     * @throws StringIndexOutOfBoundsException
416     *             if {@code offset} is negative or greater than the current
417     *             {@code length()}.
418     * @see String#valueOf(int)
419     */
420    public StringBuilder insert(int offset, int i) {
421        insert0(offset, Integer.toString(i));
422        return this;
423    }
424
425    /**
426     * Inserts the string representation of the specified {@code long} value at
427     * the specified {@code offset}. The {@code long} value is converted to a
428     * String according to the rule defined by {@link String#valueOf(long)}.
429     *
430     * @param offset
431     *            the index to insert at.
432     * @param l
433     *            the {@code long} value to insert.
434     * @return this builder.
435     * @throws StringIndexOutOfBoundsException
436     *             if {@code offset} is negative or greater than the current
437     *             {code length()}.
438     * @see String#valueOf(long)
439     */
440    public StringBuilder insert(int offset, long l) {
441        insert0(offset, Long.toString(l));
442        return this;
443    }
444
445    /**
446     * Inserts the string representation of the specified {@code float} value at
447     * the specified {@code offset}. The {@code float} value is converted to a
448     * string according to the rule defined by {@link String#valueOf(float)}.
449     *
450     * @param offset
451     *            the index to insert at.
452     * @param f
453     *            the {@code float} value to insert.
454     * @return this builder.
455     * @throws StringIndexOutOfBoundsException
456     *             if {@code offset} is negative or greater than the current
457     *             {@code length()}.
458     * @see String#valueOf(float)
459     */
460    public StringBuilder insert(int offset, float f) {
461        insert0(offset, Float.toString(f));
462        return this;
463    }
464
465    /**
466     * Inserts the string representation of the specified {@code double} value
467     * at the specified {@code offset}. The {@code double} value is converted
468     * to a String according to the rule defined by
469     * {@link String#valueOf(double)}.
470     *
471     * @param offset
472     *            the index to insert at.
473     * @param d
474     *            the {@code double} value to insert.
475     * @return this builder.
476     * @throws StringIndexOutOfBoundsException
477     *             if {@code offset} is negative or greater than the current
478     *             {@code length()}.
479     * @see String#valueOf(double)
480     */
481    public StringBuilder insert(int offset, double d) {
482        insert0(offset, Double.toString(d));
483        return this;
484    }
485
486    /**
487     * Inserts the string representation of the specified {@code Object} at the
488     * specified {@code offset}. The {@code Object} value is converted to a
489     * String according to the rule defined by {@link String#valueOf(Object)}.
490     *
491     * @param offset
492     *            the index to insert at.
493     * @param obj
494     *            the {@code Object} to insert.
495     * @return this builder.
496     * @throws StringIndexOutOfBoundsException
497     *             if {@code offset} is negative or greater than the current
498     *             {@code length()}.
499     * @see String#valueOf(Object)
500     */
501    public StringBuilder insert(int offset, Object obj) {
502        insert0(offset, obj == null ? "null" : obj.toString()); //$NON-NLS-1$
503        return this;
504    }
505
506    /**
507     * Inserts the specified string at the specified {@code offset}. If the
508     * specified string is null, then the String {@code "null"} is inserted.
509     *
510     * @param offset
511     *            the index to insert at.
512     * @param str
513     *            the {@code String} to insert.
514     * @return this builder.
515     * @throws StringIndexOutOfBoundsException
516     *             if {@code offset} is negative or greater than the current
517     *             {@code length()}.
518     */
519    public StringBuilder insert(int offset, String str) {
520        insert0(offset, str);
521        return this;
522    }
523
524    /**
525     * Inserts the string representation of the specified {@code char[]} at the
526     * specified {@code offset}. The {@code char[]} value is converted to a
527     * String according to the rule defined by {@link String#valueOf(char[])}.
528     *
529     * @param offset
530     *            the index to insert at.
531     * @param ch
532     *            the {@code char[]} to insert.
533     * @return this builder.
534     * @throws StringIndexOutOfBoundsException
535     *             if {@code offset} is negative or greater than the current
536     *             {@code length()}.
537     * @see String#valueOf(char[])
538     */
539    public StringBuilder insert(int offset, char[] ch) {
540        insert0(offset, ch);
541        return this;
542    }
543
544    /**
545     * Inserts the string representation of the specified subsequence of the
546     * {@code char[]} at the specified {@code offset}. The {@code char[]} value
547     * is converted to a String according to the rule defined by
548     * {@link String#valueOf(char[],int,int)}.
549     *
550     * @param offset
551     *            the index to insert at.
552     * @param str
553     *            the {@code char[]} to insert.
554     * @param strOffset
555     *            the inclusive index.
556     * @param strLen
557     *            the number of characters.
558     * @return this builder.
559     * @throws StringIndexOutOfBoundsException
560     *             if {@code offset} is negative or greater than the current
561     *             {@code length()}, or {@code strOffset} and {@code strLen} do
562     *             not specify a valid subsequence.
563     * @see String#valueOf(char[],int,int)
564     */
565    public StringBuilder insert(int offset, char[] str, int strOffset,
566            int strLen) {
567        insert0(offset, str, strOffset, strLen);
568        return this;
569    }
570
571    /**
572     * Inserts the string representation of the specified {@code CharSequence}
573     * at the specified {@code offset}. The {@code CharSequence} is converted
574     * to a String as defined by {@link CharSequence#toString()}. If {@code s}
575     * is {@code null}, then the String {@code "null"} is inserted.
576     *
577     * @param offset
578     *            the index to insert at.
579     * @param s
580     *            the {@code CharSequence} to insert.
581     * @return this builder.
582     * @throws IndexOutOfBoundsException
583     *             if {@code offset} is negative or greater than the current
584     *             {@code length()}.
585     * @see CharSequence#toString()
586     */
587    public StringBuilder insert(int offset, CharSequence s) {
588        insert0(offset, s == null ? "null" : s.toString()); //$NON-NLS-1$
589        return this;
590    }
591
592    /**
593     * Inserts the string representation of the specified subsequence of the
594     * {@code CharSequence} at the specified {@code offset}. The {@code
595     * CharSequence} is converted to a String as defined by
596     * {@link CharSequence#subSequence(int, int)}. If the {@code CharSequence}
597     * is {@code null}, then the string {@code "null"} is used to determine the
598     * subsequence.
599     *
600     * @param offset
601     *            the index to insert at.
602     * @param s
603     *            the {@code CharSequence} to insert.
604     * @param start
605     *            the start of the subsequence of the character sequence.
606     * @param end
607     *            the end of the subsequence of the character sequence.
608     * @return this builder.
609     * @throws IndexOutOfBoundsException
610     *             if {@code offset} is negative or greater than the current
611     *             {@code length()}, or {@code start} and {@code end} do not
612     *             specify a valid subsequence.
613     * @see CharSequence#subSequence(int, int)
614     */
615    public StringBuilder insert(int offset, CharSequence s, int start, int end) {
616        insert0(offset, s, start, end);
617        return this;
618    }
619
620    /**
621     * Replaces the specified subsequence in this builder with the specified
622     * string.
623     *
624     * @param start
625     *            the inclusive begin index.
626     * @param end
627     *            the exclusive end index.
628     * @param str
629     *            the replacement string.
630     * @return this builder.
631     * @throws StringIndexOutOfBoundsException
632     *             if {@code start} is negative, greater than the current
633     *             {@code length()} or greater than {@code end}.
634     * @throws NullPointerException
635     *            if {@code str} is {@code null}.
636     */
637    public StringBuilder replace(int start, int end, String str) {
638        replace0(start, end, str);
639        return this;
640    }
641
642    /**
643     * Reverses the order of characters in this builder.
644     *
645     * @return this buffer.
646     */
647    public StringBuilder reverse() {
648        reverse0();
649        return this;
650    }
651
652    /**
653     * Returns the contents of this builder.
654     *
655     * @return the string representation of the data in this builder.
656     */
657    @Override
658    public String toString() {
659        /* Note: This method is required to workaround a compiler bug
660         * in the RI javac (at least in 1.5.0_06) that will generate a
661         * reference to the non-public AbstractStringBuilder if we don't
662         * override it here.
663         */
664        return super.toString();
665    }
666
667    /**
668     * Reads the state of a {@code StringBuilder} from the passed stream and
669     * restores it to this instance.
670     *
671     * @param in
672     *            the stream to read the state from.
673     * @throws IOException
674     *             if the stream throws it during the read.
675     * @throws ClassNotFoundException
676     *             if the stream throws it during the read.
677     */
678    private void readObject(ObjectInputStream in) throws IOException,
679            ClassNotFoundException {
680        in.defaultReadObject();
681        int count = in.readInt();
682        char[] value = (char[]) in.readObject();
683        set(value, count);
684    }
685
686    /**
687     * Writes the state of this object to the stream passed.
688     *
689     * @param out
690     *            the stream to write the state to.
691     * @throws IOException
692     *             if the stream throws it during the write.
693     * @serialData {@code int} - the length of this object. {@code char[]} - the
694     *             buffer from this object, which may be larger than the length
695     *             field.
696     */
697    private void writeObject(ObjectOutputStream out) throws IOException {
698        out.defaultWriteObject();
699        out.writeInt(length());
700        out.writeObject(getValue());
701    }
702}
703