1 /* AbstractStringBuffer.java -- Growable strings
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
41 import java
.io
.Serializable
;
44 * This class is based on gnu.classpath.ClasspathStringBuffer but
45 * is package-private to java.lang so it can be used as the basis
46 * for StringBuffer and StringBuilder.
47 * If you modify this, please consider also modifying that code.
49 abstract class AbstractStringBuffer
50 implements Serializable
, CharSequence
, Appendable
54 * Index of next available character (and thus the size of the current
55 * string contents). Note that this has permissions set this way so that
56 * String can get the value.
58 * @serial the number of characters in the buffer
63 * The buffer. Note that this has permissions set this way so that String
71 * The default capacity of a buffer.
73 private static final int DEFAULT_CAPACITY
= 16;
76 * Create a new AbstractStringBuffer with default capacity 16.
78 AbstractStringBuffer()
80 this(DEFAULT_CAPACITY
);
84 * Create an empty <code>StringBuffer</code> with the specified initial
87 * @param capacity the initial capacity
88 * @throws NegativeArraySizeException if capacity is negative
90 AbstractStringBuffer(int capacity
)
92 value
= new char[capacity
];
96 * Create a new <code>StringBuffer</code> with the characters in the
97 * specified <code>String</code>. Initial capacity will be the size of the
100 * @param str the <code>String</code> to convert
101 * @throws NullPointerException if str is null
103 AbstractStringBuffer(String str
)
106 value
= new char[count
+ DEFAULT_CAPACITY
];
107 str
.getChars(0, count
, value
, 0);
111 * Create a new <code>StringBuffer</code> with the characters in the
112 * specified <code>CharSequence</code>. Initial capacity will be the
113 * length of the sequence plus 16; if the sequence reports a length
114 * less than or equal to 0, then the initial capacity will be 16.
116 * @param seq the initializing <code>CharSequence</code>
117 * @throws NullPointerException if str is null
120 AbstractStringBuffer(CharSequence seq
)
122 int len
= seq
.length();
123 count
= len
<= 0 ?
0 : len
;
124 value
= new char[count
+ DEFAULT_CAPACITY
];
125 for (int i
= 0; i
< len
; ++i
)
126 value
[i
] = seq
.charAt(i
);
130 * Increase the capacity of this <code>StringBuffer</code>. This will
131 * ensure that an expensive growing operation will not occur until
132 * <code>minimumCapacity</code> is reached. The buffer is grown to the
133 * larger of <code>minimumCapacity</code> and
134 * <code>capacity() * 2 + 2</code>, if it is not already large enough.
136 * @param minimumCapacity the new capacity
139 public void ensureCapacity(int minimumCapacity
)
141 ensureCapacity_unsynchronized(minimumCapacity
);
145 * Set the length of this StringBuffer. If the new length is greater than
146 * the current length, all the new characters are set to '\0'. If the new
147 * length is less than the current length, the first <code>newLength</code>
148 * characters of the old array will be preserved, and the remaining
149 * characters are truncated.
151 * @param newLength the new length
152 * @throws IndexOutOfBoundsException if the new length is negative
153 * (while unspecified, this is a StringIndexOutOfBoundsException)
156 public void setLength(int newLength
)
159 throw new StringIndexOutOfBoundsException(newLength
);
161 int valueLength
= value
.length
;
163 /* Always call ensureCapacity_unsynchronized in order to preserve
164 copy-on-write semantics. */
165 ensureCapacity_unsynchronized(newLength
);
167 if (newLength
< valueLength
)
169 /* If the StringBuffer's value just grew, then we know that
170 value is newly allocated and the region between count and
171 newLength is filled with '\0'. */
176 /* The StringBuffer's value doesn't need to grow. However,
177 we should clear out any cruft that may exist. */
178 while (count
< newLength
)
179 value
[count
++] = '\0';
184 * Get the character at the specified index.
186 * @param index the index of the character to get, starting at 0
187 * @return the character at the specified index
188 * @throws IndexOutOfBoundsException if index is negative or >= length()
189 * (while unspecified, this is a StringIndexOutOfBoundsException)
191 public char charAt(int index
)
193 if (index
< 0 || index
>= count
)
194 throw new StringIndexOutOfBoundsException(index
);
199 * Get the code point at the specified index. This is like #charAt(int),
200 * but if the character is the start of a surrogate pair, and the
201 * following character completes the pair, then the corresponding
202 * supplementary code point is returned.
203 * @param index the index of the codepoint to get, starting at 0
204 * @return the codepoint at the specified index
205 * @throws IndexOutOfBoundsException if index is negative or >= length()
208 public int codePointAt(int index
)
210 return Character
.codePointAt(value
, index
, count
);
214 * Get the code point before the specified index. This is like
215 * #codePointAt(int), but checks the characters at <code>index-1</code> and
216 * <code>index-2</code> to see if they form a supplementary code point.
217 * @param index the index just past the codepoint to get, starting at 0
218 * @return the codepoint at the specified index
219 * @throws IndexOutOfBoundsException if index is negative or >= length()
222 public int codePointBefore(int index
)
224 // Character.codePointBefore() doesn't perform this check. We
225 // could use the CharSequence overload, but this is just as easy.
227 throw new IndexOutOfBoundsException();
228 return Character
.codePointBefore(value
, index
, 1);
232 * Get the specified array of characters. <code>srcOffset - srcEnd</code>
233 * characters will be copied into the array you pass in.
235 * @param srcOffset the index to start copying from (inclusive)
236 * @param srcEnd the index to stop copying from (exclusive)
237 * @param dst the array to copy into
238 * @param dstOffset the index to start copying into
239 * @throws NullPointerException if dst is null
240 * @throws IndexOutOfBoundsException if any source or target indices are
241 * out of range (while unspecified, source problems cause a
242 * StringIndexOutOfBoundsException, and dest problems cause an
243 * ArrayIndexOutOfBoundsException)
244 * @see System#arraycopy(Object, int, Object, int, int)
246 public void getChars(int srcOffset
, int srcEnd
,
247 char[] dst
, int dstOffset
)
249 if (srcOffset
< 0 || srcEnd
> count
|| srcEnd
< srcOffset
)
250 throw new StringIndexOutOfBoundsException();
251 System
.arraycopy(value
, srcOffset
, dst
, dstOffset
, srcEnd
- srcOffset
);
255 * Set the character at the specified index.
257 * @param index the index of the character to set starting at 0
258 * @param ch the value to set that character to
259 * @throws IndexOutOfBoundsException if index is negative or >= length()
260 * (while unspecified, this is a StringIndexOutOfBoundsException)
262 public void setCharAt(int index
, char ch
)
264 if (index
< 0 || index
>= count
)
265 throw new StringIndexOutOfBoundsException(index
);
266 // Call ensureCapacity to enforce copy-on-write.
267 ensureCapacity_unsynchronized(count
);
272 * Append the <code>String</code> value of the argument to this
273 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
274 * to <code>String</code>.
276 * @param obj the <code>Object</code> to convert and append
277 * @return this <code>StringBuffer</code>
278 * @see String#valueOf(Object)
279 * @see #append(String)
281 public AbstractStringBuffer
append(Object obj
)
283 return append(String
.valueOf(obj
));
287 * Append the <code>String</code> to this <code>StringBuffer</code>. If
288 * str is null, the String "null" is appended.
290 * @param str the <code>String</code> to append
291 * @return this <code>StringBuffer</code>
293 public AbstractStringBuffer
append(String str
)
298 ensureCapacity_unsynchronized(count
+ len
);
299 str
.getChars(0, len
, value
, count
);
305 * Append the <code>StringBuilder</code> value of the argument to this
306 * <code>StringBuilder</code>. This behaves the same as
307 * <code>append((Object) stringBuffer)</code>, except it is more efficient.
309 * @param stringBuffer the <code>StringBuilder</code> to convert and append
310 * @return this <code>StringBuilder</code>
311 * @see #append(Object)
313 public AbstractStringBuffer
append(StringBuffer stringBuffer
)
315 if (stringBuffer
== null)
316 return append("null");
317 synchronized (stringBuffer
)
319 int len
= stringBuffer
.count
;
320 ensureCapacity(count
+ len
);
321 System
.arraycopy(stringBuffer
.value
, 0, value
, count
, len
);
328 * Append the <code>char</code> array to this <code>StringBuffer</code>.
329 * This is similar (but more efficient) than
330 * <code>append(new String(data))</code>, except in the case of null.
332 * @param data the <code>char[]</code> to append
333 * @return this <code>StringBuffer</code>
334 * @throws NullPointerException if <code>str</code> is <code>null</code>
335 * @see #append(char[], int, int)
337 public AbstractStringBuffer
append(char[] data
)
339 return append(data
, 0, data
.length
);
343 * Append part of the <code>char</code> array to this
344 * <code>StringBuffer</code>. This is similar (but more efficient) than
345 * <code>append(new String(data, offset, count))</code>, except in the case
348 * @param data the <code>char[]</code> to append
349 * @param offset the start location in <code>str</code>
350 * @param count the number of characters to get from <code>str</code>
351 * @return this <code>StringBuffer</code>
352 * @throws NullPointerException if <code>str</code> is <code>null</code>
353 * @throws IndexOutOfBoundsException if offset or count is out of range
354 * (while unspecified, this is a StringIndexOutOfBoundsException)
356 public AbstractStringBuffer
append(char[] data
, int offset
, int count
)
358 if (offset
< 0 || count
< 0 || offset
> data
.length
- count
)
359 throw new StringIndexOutOfBoundsException();
360 ensureCapacity_unsynchronized(this.count
+ count
);
361 System
.arraycopy(data
, offset
, value
, this.count
, count
);
367 * Append the <code>String</code> value of the argument to this
368 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
369 * to <code>String</code>.
371 * @param bool the <code>boolean</code> to convert and append
372 * @return this <code>StringBuffer</code>
373 * @see String#valueOf(boolean)
375 public AbstractStringBuffer
append(boolean bool
)
377 return append(bool ?
"true" : "false");
381 * Append the <code>char</code> to this <code>StringBuffer</code>.
383 * @param ch the <code>char</code> to append
384 * @return this <code>StringBuffer</code>
386 public AbstractStringBuffer
append(char ch
)
388 ensureCapacity_unsynchronized(count
+ 1);
394 * Append the characters in the <code>CharSequence</code> to this
397 * @param seq the <code>CharSequence</code> providing the characters
398 * @return this <code>StringBuffer</code>
401 public AbstractStringBuffer
append(CharSequence seq
)
403 return append(seq
, 0, seq
.length());
407 * Append some characters from the <code>CharSequence</code> to this
408 * buffer. If the argument is null, the <code>seq</code> is assumed
409 * to be equal to the string <code>"null"</code>.
411 * @param seq the <code>CharSequence</code> providing the characters
412 * @param start the starting index
413 * @param end one past the final index
414 * @return this <code>StringBuffer</code>
417 public AbstractStringBuffer
append(CharSequence seq
, int start
, int end
)
423 ensureCapacity_unsynchronized(count
+ end
- start
);
424 for (; start
< end
; ++start
)
425 value
[count
++] = seq
.charAt(start
);
431 * Append the <code>String</code> value of the argument to this
432 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
433 * to <code>String</code>.
435 * @param inum the <code>int</code> to convert and append
436 * @return this <code>StringBuffer</code>
437 * @see String#valueOf(int)
439 // GCJ LOCAL: this is native for efficiency.
440 public native AbstractStringBuffer
append (int inum
);
443 * Append the <code>String</code> value of the argument to this
444 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
445 * to <code>String</code>.
447 * @param lnum the <code>long</code> to convert and append
448 * @return this <code>StringBuffer</code>
449 * @see String#valueOf(long)
451 public AbstractStringBuffer
append(long lnum
)
453 return append(Long
.toString(lnum
, 10));
457 * Append the <code>String</code> value of the argument to this
458 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
459 * to <code>String</code>.
461 * @param fnum the <code>float</code> to convert and append
462 * @return this <code>StringBuffer</code>
463 * @see String#valueOf(float)
465 public AbstractStringBuffer
append(float fnum
)
467 return append(Float
.toString(fnum
));
471 * Append the <code>String</code> value of the argument to this
472 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
473 * to <code>String</code>.
475 * @param dnum the <code>double</code> to convert and append
476 * @return this <code>StringBuffer</code>
477 * @see String#valueOf(double)
479 public AbstractStringBuffer
append(double dnum
)
481 return append(Double
.toString(dnum
));
485 * Append the code point to this <code>StringBuffer</code>.
486 * This is like #append(char), but will append two characters
487 * if a supplementary code point is given.
489 * @param code the code point to append
490 * @return this <code>StringBuffer</code>
491 * @see Character#toChars(int, char[], int)
494 public AbstractStringBuffer
appendCodePoint(int code
)
496 int len
= Character
.charCount(code
);
497 ensureCapacity_unsynchronized(count
+ len
);
498 Character
.toChars(code
, value
, count
);
504 * Delete characters from this <code>StringBuffer</code>.
505 * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
506 * harmless for end to be larger than length().
508 * @param start the first character to delete
509 * @param end the index after the last character to delete
510 * @return this <code>StringBuffer</code>
511 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
514 public AbstractStringBuffer
delete(int start
, int end
)
516 if (start
< 0 || start
> count
|| start
> end
)
517 throw new StringIndexOutOfBoundsException(start
);
520 ensureCapacity_unsynchronized(count
);
521 if (count
- end
!= 0)
522 System
.arraycopy(value
, end
, value
, start
, count
- end
);
523 count
-= end
- start
;
528 * Delete a character from this <code>StringBuffer</code>.
530 * @param index the index of the character to delete
531 * @return this <code>StringBuffer</code>
532 * @throws StringIndexOutOfBoundsException if index is out of bounds
535 public AbstractStringBuffer
deleteCharAt(int index
)
537 return delete(index
, index
+ 1);
541 * Replace characters between index <code>start</code> (inclusive) and
542 * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
543 * is larger than the size of this StringBuffer, all characters after
544 * <code>start</code> are replaced.
546 * @param start the beginning index of characters to delete (inclusive)
547 * @param end the ending index of characters to delete (exclusive)
548 * @param str the new <code>String</code> to insert
549 * @return this <code>StringBuffer</code>
550 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
551 * @throws NullPointerException if str is null
554 public AbstractStringBuffer
replace(int start
, int end
, String str
)
556 if (start
< 0 || start
> count
|| start
> end
)
557 throw new StringIndexOutOfBoundsException(start
);
560 // Calculate the difference in 'count' after the replace.
561 int delta
= len
- (end
> count ? count
: end
) + start
;
562 ensureCapacity_unsynchronized(count
+ delta
);
564 if (delta
!= 0 && end
< count
)
565 System
.arraycopy(value
, end
, value
, end
+ delta
, count
- end
);
567 str
.getChars(0, len
, value
, start
);
573 * Insert a subarray of the <code>char[]</code> argument into this
574 * <code>StringBuffer</code>.
576 * @param offset the place to insert in this buffer
577 * @param str the <code>char[]</code> to insert
578 * @param str_offset the index in <code>str</code> to start inserting from
579 * @param len the number of characters to insert
580 * @return this <code>StringBuffer</code>
581 * @throws NullPointerException if <code>str</code> is <code>null</code>
582 * @throws StringIndexOutOfBoundsException if any index is out of bounds
585 public AbstractStringBuffer
insert(int offset
, char[] str
, int str_offset
, int len
)
587 if (offset
< 0 || offset
> count
|| len
< 0
588 || str_offset
< 0 || str_offset
> str
.length
- len
)
589 throw new StringIndexOutOfBoundsException();
590 ensureCapacity_unsynchronized(count
+ len
);
591 System
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
592 System
.arraycopy(str
, str_offset
, value
, offset
, len
);
598 * Insert the <code>String</code> value of the argument into this
599 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
600 * to <code>String</code>.
602 * @param offset the place to insert in this buffer
603 * @param obj the <code>Object</code> to convert and insert
604 * @return this <code>StringBuffer</code>
605 * @exception StringIndexOutOfBoundsException if offset is out of bounds
606 * @see String#valueOf(Object)
608 public AbstractStringBuffer
insert(int offset
, Object obj
)
610 return insert(offset
, obj
== null ?
"null" : obj
.toString());
614 * Insert the <code>String</code> argument into this
615 * <code>StringBuffer</code>. If str is null, the String "null" is used
618 * @param offset the place to insert in this buffer
619 * @param str the <code>String</code> to insert
620 * @return this <code>StringBuffer</code>
621 * @throws StringIndexOutOfBoundsException if offset is out of bounds
623 public AbstractStringBuffer
insert(int offset
, String str
)
625 if (offset
< 0 || offset
> count
)
626 throw new StringIndexOutOfBoundsException(offset
);
630 ensureCapacity_unsynchronized(count
+ len
);
631 System
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
632 str
.getChars(0, len
, value
, offset
);
638 * Insert the <code>CharSequence</code> argument into this
639 * <code>StringBuffer</code>. If the sequence is null, the String
640 * "null" is used instead.
642 * @param offset the place to insert in this buffer
643 * @param sequence the <code>CharSequence</code> to insert
644 * @return this <code>StringBuffer</code>
645 * @throws IndexOutOfBoundsException if offset is out of bounds
648 public AbstractStringBuffer
insert(int offset
, CharSequence sequence
)
650 if (sequence
== null)
652 return insert(offset
, sequence
, 0, sequence
.length());
656 * Insert a subsequence of the <code>CharSequence</code> argument into this
657 * <code>StringBuffer</code>. If the sequence is null, the String
658 * "null" is used instead.
660 * @param offset the place to insert in this buffer
661 * @param sequence the <code>CharSequence</code> to insert
662 * @param start the starting index of the subsequence
663 * @param end one past the ending index of the subsequence
664 * @return this <code>StringBuffer</code>
665 * @throws IndexOutOfBoundsException if offset, start,
666 * or end are out of bounds
669 public AbstractStringBuffer
insert(int offset
, CharSequence sequence
, int start
, int end
)
671 if (sequence
== null)
673 if (start
< 0 || end
< 0 || start
> end
|| end
> sequence
.length())
674 throw new IndexOutOfBoundsException();
675 int len
= end
- start
;
676 ensureCapacity_unsynchronized(count
+ len
);
677 System
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
678 for (int i
= start
; i
< end
; ++i
)
679 value
[offset
++] = sequence
.charAt(i
);
685 * Insert the <code>char[]</code> argument into this
686 * <code>StringBuffer</code>.
688 * @param offset the place to insert in this buffer
689 * @param data the <code>char[]</code> to insert
690 * @return this <code>StringBuffer</code>
691 * @throws NullPointerException if <code>data</code> is <code>null</code>
692 * @throws StringIndexOutOfBoundsException if offset is out of bounds
693 * @see #insert(int, char[], int, int)
695 public AbstractStringBuffer
insert(int offset
, char[] data
)
697 return insert(offset
, data
, 0, data
.length
);
701 * Insert the <code>String</code> value of the argument into this
702 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
703 * to <code>String</code>.
705 * @param offset the place to insert in this buffer
706 * @param bool the <code>boolean</code> to convert and insert
707 * @return this <code>StringBuffer</code>
708 * @throws StringIndexOutOfBoundsException if offset is out of bounds
709 * @see String#valueOf(boolean)
711 public AbstractStringBuffer
insert(int offset
, boolean bool
)
713 return insert(offset
, bool ?
"true" : "false");
717 * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
719 * @param offset the place to insert in this buffer
720 * @param ch the <code>char</code> to insert
721 * @return this <code>StringBuffer</code>
722 * @throws StringIndexOutOfBoundsException if offset is out of bounds
724 public AbstractStringBuffer
insert(int offset
, char ch
)
726 if (offset
< 0 || offset
> count
)
727 throw new StringIndexOutOfBoundsException(offset
);
728 ensureCapacity_unsynchronized(count
+ 1);
729 System
.arraycopy(value
, offset
, value
, offset
+ 1, count
- offset
);
736 * Insert the <code>String</code> value of the argument into this
737 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
738 * to <code>String</code>.
740 * @param offset the place to insert in this buffer
741 * @param inum the <code>int</code> to convert and insert
742 * @return this <code>StringBuffer</code>
743 * @throws StringIndexOutOfBoundsException if offset is out of bounds
744 * @see String#valueOf(int)
746 public AbstractStringBuffer
insert(int offset
, int inum
)
748 return insert(offset
, String
.valueOf(inum
));
752 * Insert the <code>String</code> value of the argument into this
753 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
754 * to <code>String</code>.
756 * @param offset the place to insert in this buffer
757 * @param lnum the <code>long</code> to convert and insert
758 * @return this <code>StringBuffer</code>
759 * @throws StringIndexOutOfBoundsException if offset is out of bounds
760 * @see String#valueOf(long)
762 public AbstractStringBuffer
insert(int offset
, long lnum
)
764 return insert(offset
, Long
.toString(lnum
, 10));
768 * Insert the <code>String</code> value of the argument into this
769 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
770 * to <code>String</code>.
772 * @param offset the place to insert in this buffer
773 * @param fnum the <code>float</code> to convert and insert
774 * @return this <code>StringBuffer</code>
775 * @throws StringIndexOutOfBoundsException if offset is out of bounds
776 * @see String#valueOf(float)
778 public AbstractStringBuffer
insert(int offset
, float fnum
)
780 return insert(offset
, Float
.toString(fnum
));
784 * Insert the <code>String</code> value of the argument into this
785 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
786 * to <code>String</code>.
788 * @param offset the place to insert in this buffer
789 * @param dnum the <code>double</code> to convert and insert
790 * @return this <code>StringBuffer</code>
791 * @throws StringIndexOutOfBoundsException if offset is out of bounds
792 * @see String#valueOf(double)
794 public AbstractStringBuffer
insert(int offset
, double dnum
)
796 return insert(offset
, Double
.toString(dnum
));
800 * Finds the first instance of a substring in this StringBuilder.
802 * @param str String to find
803 * @return location (base 0) of the String, or -1 if not found
804 * @throws NullPointerException if str is null
805 * @see #indexOf(String, int)
807 public int indexOf(String str
)
809 return indexOf(str
, 0);
813 * Finds the first instance of a String in this StringBuffer, starting at
814 * a given index. If starting index is less than 0, the search starts at
815 * the beginning of this String. If the starting index is greater than the
816 * length of this String, or the substring is not found, -1 is returned.
818 * @param str String to find
819 * @param fromIndex index to start the search
820 * @return location (base 0) of the String, or -1 if not found
821 * @throws NullPointerException if str is null
824 public int indexOf(String str
, int fromIndex
)
828 int limit
= count
- str
.count
;
829 for ( ; fromIndex
<= limit
; fromIndex
++)
830 if (regionMatches(fromIndex
, str
))
836 * Finds the last instance of a substring in this StringBuffer.
838 * @param str String to find
839 * @return location (base 0) of the String, or -1 if not found
840 * @throws NullPointerException if str is null
841 * @see #lastIndexOf(String, int)
844 public int lastIndexOf(String str
)
846 return lastIndexOf(str
, count
- str
.count
);
850 * Finds the last instance of a String in this StringBuffer, starting at a
851 * given index. If starting index is greater than the maximum valid index,
852 * then the search begins at the end of this String. If the starting index
853 * is less than zero, or the substring is not found, -1 is returned.
855 * @param str String to find
856 * @param fromIndex index to start the search
857 * @return location (base 0) of the String, or -1 if not found
858 * @throws NullPointerException if str is null
861 public int lastIndexOf(String str
, int fromIndex
)
863 fromIndex
= Math
.min(fromIndex
, count
- str
.count
);
864 for ( ; fromIndex
>= 0; fromIndex
--)
865 if (regionMatches(fromIndex
, str
))
871 * Reverse the characters in this StringBuffer. The same sequence of
872 * characters exists, but in the reverse index ordering.
874 * @return this <code>StringBuffer</code>
876 public AbstractStringBuffer
reverse()
878 // Call ensureCapacity to enforce copy-on-write.
879 ensureCapacity_unsynchronized(count
);
880 for (int i
= count
>> 1, j
= count
- i
; --i
>= 0; ++j
)
890 * This may reduce the amount of memory used by the StringBuffer,
891 * by resizing the internal array to remove unused space. However,
892 * this method is not required to resize, so this behavior cannot
896 public void trimToSize()
898 int wouldSave
= value
.length
- count
;
899 // Some random heuristics: if we save less than 20 characters, who
903 // If we save more than 200 characters, shrink.
904 // If we save more than 1/4 of the buffer, shrink.
905 if (wouldSave
> 200 || wouldSave
* 4 > value
.length
)
907 char[] newValue
= new char[count
];
908 System
.arraycopy(value
, 0, newValue
, 0, count
);
914 * Return the number of code points between two indices in the
915 * <code>StringBuffer</code>. An unpaired surrogate counts as a
916 * code point for this purpose. Characters outside the indicated
917 * range are not examined, even if the range ends in the middle of a
920 * @param start the starting index
921 * @param end one past the ending index
922 * @return the number of code points
925 public int codePointCount(int start
, int end
)
927 if (start
< 0 || end
>= count
|| start
> end
)
928 throw new StringIndexOutOfBoundsException();
933 char base
= value
[start
];
934 if (base
< Character
.MIN_HIGH_SURROGATE
935 || base
> Character
.MAX_HIGH_SURROGATE
938 || value
[start
+ 1] < Character
.MIN_LOW_SURROGATE
939 || value
[start
+ 1] > Character
.MAX_LOW_SURROGATE
)
955 * Starting at the given index, this counts forward by the indicated
956 * number of code points, and then returns the resulting index. An
957 * unpaired surrogate counts as a single code point for this
960 * @param start the starting index
961 * @param codePoints the number of code points
962 * @return the resulting index
965 public int offsetByCodePoints(int start
, int codePoints
)
967 while (codePoints
> 0)
969 char base
= value
[start
];
970 if (base
< Character
.MIN_HIGH_SURROGATE
971 || base
> Character
.MAX_HIGH_SURROGATE
973 || value
[start
+ 1] < Character
.MIN_LOW_SURROGATE
974 || value
[start
+ 1] > Character
.MAX_LOW_SURROGATE
)
990 * Increase the capacity of this <code>StringBuilder</code>. This will
991 * ensure that an expensive growing operation will not occur until
992 * <code>minimumCapacity</code> is reached. The buffer is grown to the
993 * larger of <code>minimumCapacity</code> and
994 * <code>capacity() * 2 + 2</code>, if it is not already large enough.
996 * @param minimumCapacity the new capacity
999 void ensureCapacity_unsynchronized(int minimumCapacity
)
1001 if (minimumCapacity
> value
.length
)
1003 int max
= value
.length
* 2 + 2;
1004 minimumCapacity
= (minimumCapacity
< max ? max
: minimumCapacity
);
1005 char[] nb
= new char[minimumCapacity
];
1006 System
.arraycopy(value
, 0, nb
, 0, count
);
1012 * Predicate which determines if a substring of this matches another String
1013 * starting at a specified offset for each String and continuing for a
1014 * specified length. This is more efficient than creating a String to call
1017 * @param toffset index to start comparison at for this String
1018 * @param other non-null String to compare to region of this
1019 * @return true if regions match, false otherwise
1020 * @see #indexOf(String, int)
1021 * @see #lastIndexOf(String, int)
1022 * @see String#regionMatches(boolean, int, String, int, int)
1024 // GCJ LOCAL: native for gcj.
1025 private native boolean regionMatches(int toffset
, String other
);