]>
Commit | Line | Data |
---|---|---|
ee9dd372 TT |
1 | // StringBuffer.java - Growable strings. |
2 | ||
2a198bc4 | 3 | /* Copyright (C) 1998, 1999, 2000 Red Hat |
ee9dd372 TT |
4 | |
5 | This file is part of libgcj. | |
6 | ||
7 | This software is copyrighted work licensed under the terms of the | |
8 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for | |
9 | details. */ | |
10 | ||
11 | package java.lang; | |
12 | import java.io.Serializable; | |
13 | ||
14 | /** | |
15 | * @author Tom Tromey <tromey@cygnus.com> | |
16 | * @date October 23, 1998. | |
17 | */ | |
18 | ||
19 | /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 | |
2238de65 TT |
20 | * Updated using online JDK 1.2 docs. |
21 | * Believed complete and correct to JDK 1.2. | |
22 | * Merged with Classpath. | |
ee9dd372 TT |
23 | */ |
24 | ||
2238de65 TT |
25 | /** |
26 | * <code>StringBuffer</code> represents a changeable <code>String</code>. | |
27 | * It provides the operations required to modify the | |
28 | * <code>StringBuffer</code> including insert, replace, delete, append, | |
29 | * and reverse. | |
30 | * <P> | |
31 | * | |
32 | * <code>StringBuffer</code>s are variable-length in nature, so even if | |
33 | * you initialize them to a certain size, they can still grow larger than | |
34 | * that. <EM>Capacity</EM> indicates the number of characters the | |
35 | * <code>StringBuffer</code> can have in it before it has to grow (growing | |
36 | * the char array is an expensive operation involving <code>new</code>). | |
37 | * <P> | |
38 | * | |
39 | * Incidentally, the String operator "+" actually is turned into a | |
40 | * <code>StringBuffer</code> operation: | |
41 | * <BR> | |
42 | * <code>a + b</code> | |
43 | * <BR> | |
44 | * is the same as | |
45 | * <BR> | |
46 | * <code>new StringBuffer(a).append(b).toString()</code>. | |
47 | * | |
48 | * @implnote Classpath's StringBuffer is capable of sharing memory with | |
49 | * Strings for efficiency. This will help in two instances: | |
50 | * first, when a StringBuffer is created from a String but is | |
51 | * never changed, and second, when a StringBuffer is converted | |
52 | * to a String and the StringBuffer is not changed after that. | |
53 | * | |
54 | * @since JDK1.0 | |
55 | * @author Paul Fisher | |
56 | * @author John Keiser | |
57 | * @author Tom Tromey | |
58 | * @see java.lang.String | |
59 | */ | |
ee9dd372 TT |
60 | public final class StringBuffer implements Serializable |
61 | { | |
2238de65 TT |
62 | /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. |
63 | * Uses <code>String.valueOf()</code> to convert to | |
64 | * <code>String</code>. | |
65 | * @param bool the <code>boolean</code> to convert and append. | |
66 | * @return this <code>StringBuffer</code>. | |
67 | * @see java.lang.String#valueOf(boolean) | |
68 | */ | |
ee9dd372 | 69 | public StringBuffer append (boolean bool) |
2238de65 TT |
70 | { |
71 | return append (String.valueOf(bool)); | |
72 | } | |
73 | ||
74 | /** Append the <code>char</code> to this <code>StringBuffer</code>. | |
75 | * @param c the <code>char</code> to append. | |
76 | * @return this <code>StringBuffer</code>. | |
77 | */ | |
ee9dd372 | 78 | public synchronized StringBuffer append (char ch) |
2238de65 TT |
79 | { |
80 | ensureCapacity_unsynchronized (count + 1); | |
81 | value[count++] = ch; | |
82 | return this; | |
83 | } | |
84 | ||
85 | /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
86 | * Uses <code>String.valueOf()</code> to convert to | |
87 | * <code>String</code>. | |
88 | * @param inum the <code>int</code> to convert and append. | |
89 | * @return this <code>StringBuffer</code>. | |
90 | * @see java.lang.String#valueOf(int) | |
91 | */ | |
ee9dd372 | 92 | public StringBuffer append (int inum) |
2238de65 TT |
93 | { |
94 | return append (String.valueOf(inum)); | |
95 | } | |
96 | ||
97 | /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
98 | * Uses <code>String.valueOf()</code> to convert to | |
99 | * <code>String</code>. | |
100 | * @param lnum the <code>long</code> to convert and append. | |
101 | * @return this <code>StringBuffer</code>. | |
102 | * @see java.lang.String#valueOf(long) | |
103 | */ | |
ee9dd372 | 104 | public StringBuffer append (long lnum) |
2238de65 TT |
105 | { |
106 | return append (String.valueOf(lnum)); | |
107 | } | |
108 | ||
109 | /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
110 | * Uses <code>String.valueOf()</code> to convert to | |
111 | * <code>String</code>. | |
112 | * @param fnum the <code>float</code> to convert and append. | |
113 | * @return this <code>StringBuffer</code>. | |
114 | * @see java.lang.String#valueOf(float) | |
115 | */ | |
ee9dd372 | 116 | public StringBuffer append (float fnum) |
2238de65 TT |
117 | { |
118 | return append (String.valueOf(fnum)); | |
119 | } | |
120 | ||
121 | /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
122 | * Uses <code>String.valueOf()</code> to convert to | |
123 | * <code>String</code>. | |
124 | * @param dnum the <code>double</code> to convert and append. | |
125 | * @return this <code>StringBuffer</code>. | |
126 | * @see java.lang.String#valueOf(double) | |
127 | */ | |
ee9dd372 | 128 | public StringBuffer append (double dnum) |
2238de65 TT |
129 | { |
130 | return append (String.valueOf(dnum)); | |
131 | } | |
132 | ||
133 | /** Append the <code>String</code> value of the argument to this <code>StringBuffer</code>. | |
134 | * Uses <code>String.valueOf()</code> to convert to | |
135 | * <code>String</code>. | |
136 | * @param obj the <code>Object</code> to convert and append. | |
137 | * @return this <code>StringBuffer</code>. | |
138 | * @see java.lang.String#valueOf(java.lang.Object) | |
139 | */ | |
ee9dd372 | 140 | public StringBuffer append (Object obj) |
2238de65 TT |
141 | { |
142 | return append (String.valueOf(obj)); | |
143 | } | |
144 | ||
145 | /** Append the <code>String</code> to this <code>StringBuffer</code>. | |
146 | * @param str the <code>String</code> to append. | |
147 | * @return this <code>StringBuffer</code>. | |
148 | */ | |
ee9dd372 | 149 | public synchronized StringBuffer append (String str) |
2238de65 TT |
150 | { |
151 | if (str == null) | |
152 | str = "null"; | |
153 | int len = str.length(); | |
154 | ensureCapacity_unsynchronized (count + len); | |
155 | str.getChars(0, len, value, count); | |
156 | count += len; | |
157 | return this; | |
158 | } | |
159 | ||
160 | /** Append the <code>char</code> array to this <code>StringBuffer</code>. | |
161 | * @param data the <code>char[]</code> to append. | |
162 | * @return this <code>StringBuffer</code>. | |
163 | * @exception NullPointerException if <code>str</code> is <code>null</code>. | |
164 | */ | |
ee9dd372 | 165 | public StringBuffer append (char[] data) |
2238de65 TT |
166 | { |
167 | return append (data, 0, data.length); | |
168 | } | |
169 | ||
170 | /** Append the <code>char</code> array to this <code>StringBuffer</code>. | |
171 | * @param data the <code>char[]</code> to append. | |
172 | * @param offset the place to start grabbing characters from | |
173 | * <code>str</code>. | |
174 | * @param count the number of characters to get from <code>str</code>. | |
175 | * @return this <code>StringBuffer</code>. | |
176 | * @exception NullPointerException if <code>str</code> is <code>null</code>. | |
177 | * @exception IndexOutOfBoundsException if <code>offset</code> or | |
178 | * <code>offset+len</code> is out of range. | |
179 | */ | |
ee9dd372 | 180 | public synchronized StringBuffer append (char[] data, int offset, int count) |
2238de65 TT |
181 | { |
182 | ensureCapacity_unsynchronized (this.count + count); | |
183 | System.arraycopy(data, offset, value, this.count, count); | |
184 | this.count += count; | |
185 | return this; | |
186 | } | |
187 | ||
188 | /** Get the total number of characters this <code>StringBuffer</code> | |
189 | * can support before it must be grown. Not to be confused with | |
190 | * <em>length</em>. | |
191 | * @return the capacity of this <code>StringBuffer</code> | |
192 | * @see #length() | |
193 | * @see #ensureCapacity(int) | |
194 | */ | |
ee9dd372 | 195 | public int capacity () |
2238de65 TT |
196 | { |
197 | return value.length; | |
198 | } | |
199 | ||
200 | /** Get the character at the specified index. | |
201 | * @param index the index of the character to get, starting at 0. | |
202 | * @return the character at the specified index. | |
203 | * @exception IndexOutOfBoundsException if the desired character index | |
204 | * is not between 0 and length() - 1 (inclusive). | |
205 | */ | |
ee9dd372 | 206 | public synchronized char charAt (int index) |
2238de65 TT |
207 | { |
208 | if (index >= count) | |
209 | throw new StringIndexOutOfBoundsException (index); | |
210 | return value[index]; | |
211 | } | |
212 | ||
213 | /** Delete characters from this <code>StringBuffer</code>. | |
214 | * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. | |
215 | * @param start the first character to delete. | |
216 | * @param end the index after the last character to delete. | |
217 | * @return this <code>StringBuffer</code>. | |
218 | * @exception StringIndexOutOfBoundsException if <code>start</code> | |
219 | * or <code>end-1</code> are out of bounds, or if | |
220 | * <code>start > end</code>. | |
221 | */ | |
222 | public synchronized StringBuffer delete (int start, int end) | |
223 | { | |
224 | if (start < 0 || start > count || start > end) | |
225 | throw new StringIndexOutOfBoundsException (start); | |
226 | if (end > count) | |
227 | end = count; | |
228 | // This will unshare if required. | |
229 | ensureCapacity_unsynchronized (count); | |
230 | count -= (end - start); | |
231 | System.arraycopy (value, end - 1, value, start, end - start); | |
232 | return this; | |
233 | } | |
234 | ||
235 | /** Delete a character from this <code>StringBuffer</code>. | |
236 | * @param index the index of the character to delete. | |
237 | * @return this <code>StringBuffer</code>. | |
238 | * @exception StringIndexOutOfBoundsException if <code>index</code> | |
239 | * is out of bounds. | |
240 | */ | |
241 | public StringBuffer deleteCharAt(int index) | |
242 | { | |
243 | return delete (index, index + 1); | |
244 | } | |
245 | ||
246 | /** Increase the capacity of this <code>StringBuffer</code>. | |
247 | * This will ensure that an expensive growing operation will not occur | |
248 | * until <code>minimumCapacity</code> is reached. | |
249 | * If the capacity is actually already greater than <code>minimumCapacity</code> | |
250 | * @param minimumCapacity the new capacity. | |
251 | * @see #capacity() | |
252 | */ | |
ee9dd372 | 253 | public synchronized void ensureCapacity (int minimumCapacity) |
2238de65 TT |
254 | { |
255 | if (shared || minimumCapacity > value.length) | |
256 | { | |
257 | // We don't want to make a larger vector when `shared' is | |
258 | // set. If we do, then setLength becomes very inefficient | |
259 | // when repeatedly reusing a StringBuffer in a loop. | |
260 | int max = (minimumCapacity > value.length | |
261 | ? value.length*2+2 | |
262 | : value.length); | |
263 | minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); | |
264 | char[] nb = new char[minimumCapacity]; | |
265 | System.arraycopy(value, 0, nb, 0, count); | |
266 | value = nb; | |
267 | shared = false; | |
268 | } | |
269 | } | |
bdf2ced9 AG |
270 | |
271 | // ensureCapacity is used by several synchronized methods in StringBuffer. | |
272 | // There's no need to synchronize again. | |
273 | private void ensureCapacity_unsynchronized (int minimumCapacity) | |
2238de65 TT |
274 | { |
275 | if (shared || minimumCapacity > value.length) | |
276 | { | |
277 | // We don't want to make a larger vector when `shared' is | |
278 | // set. If we do, then setLength becomes very inefficient | |
279 | // when repeatedly reusing a StringBuffer in a loop. | |
280 | int max = (minimumCapacity > value.length | |
281 | ? value.length*2+2 | |
282 | : value.length); | |
283 | minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); | |
284 | char[] nb = new char[minimumCapacity]; | |
285 | System.arraycopy(value, 0, nb, 0, count); | |
286 | value = nb; | |
287 | shared = false; | |
288 | } | |
289 | } | |
290 | ||
291 | /** Get the specified array of characters. | |
292 | * The characters will be copied into the array you pass in. | |
293 | * @param srcOffset the index to start copying from in the | |
294 | * <code>StringBuffer</code>. | |
295 | * @param srcEnd the number of characters to copy. | |
296 | * @param dst the array to copy into. | |
297 | * @param dstOffset the index to start copying into <code>dst</code>. | |
298 | * @exception NullPointerException if dst is null. | |
299 | * @exception IndexOutOfBoundsException if any source or target | |
300 | * indices are out of range. | |
301 | * @see java.lang.System#arrayCopy(java.lang.Object,int,java.lang.Object,int,int) | |
302 | */ | |
ee9dd372 TT |
303 | public synchronized void getChars (int srcOffset, int srcEnd, |
304 | char[] dst, int dstOffset) | |
2238de65 TT |
305 | { |
306 | if (srcOffset < 0 || srcOffset > srcEnd) | |
307 | throw new StringIndexOutOfBoundsException (srcOffset); | |
308 | int todo = srcEnd - srcOffset; | |
309 | if (srcEnd > count || dstOffset + todo > count) | |
310 | throw new StringIndexOutOfBoundsException (srcEnd); | |
311 | System.arraycopy(value, srcOffset, dst, dstOffset, todo); | |
312 | } | |
313 | ||
314 | /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
315 | * Uses <code>String.valueOf()</code> to convert to | |
316 | * <code>String</code>. | |
317 | * @param offset the place to insert. | |
318 | * @param bool the <code>boolean</code> to convert and insert. | |
319 | * @return this <code>StringBuffer</code>. | |
320 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
321 | * of range for this <code>StringBuffer</code>. | |
322 | * @see java.lang.String#valueOf(boolean) | |
323 | */ | |
ee9dd372 | 324 | public StringBuffer insert (int offset, boolean bool) |
2238de65 TT |
325 | { |
326 | return insert (offset, bool ? "true" : "false"); | |
327 | } | |
328 | ||
329 | /** Insert the <code>char</code> argument into this <code>StringBuffer</code>. | |
330 | * @param offset the place to insert. | |
331 | * @param ch the <code>char</code> to insert. | |
332 | * @return this <code>StringBuffer</code>. | |
333 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
334 | * of range for this <code>StringBuffer</code>. | |
335 | */ | |
ee9dd372 | 336 | public synchronized StringBuffer insert (int offset, char ch) |
2238de65 TT |
337 | { |
338 | if (offset < 0 || offset > count) | |
339 | throw new StringIndexOutOfBoundsException (offset); | |
340 | ensureCapacity_unsynchronized (count+1); | |
341 | System.arraycopy(value, offset, value, offset+1, count-offset); | |
342 | value[offset] = ch; | |
343 | count++; | |
344 | return this; | |
345 | } | |
346 | ||
347 | /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
348 | * Uses <code>String.valueOf()</code> to convert to | |
349 | * <code>String</code>. | |
350 | * @param offset the place to insert. | |
351 | * @param inum the <code>int</code> to convert and insert. | |
352 | * @return this <code>StringBuffer</code>. | |
353 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
354 | * of range for this <code>StringBuffer</code>. | |
355 | * @see java.lang.String#valueOf(int) | |
356 | */ | |
ee9dd372 | 357 | public StringBuffer insert (int offset, int inum) |
2238de65 TT |
358 | { |
359 | return insert (offset, String.valueOf(inum)); | |
360 | } | |
361 | ||
362 | /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
363 | * Uses <code>String.valueOf()</code> to convert to | |
364 | * <code>String</code>. | |
365 | * @param offset the place to insert. | |
366 | * @param lnum the <code>long</code> to convert and insert. | |
367 | * @return this <code>StringBuffer</code>. | |
368 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
369 | * of range for this <code>StringBuffer</code>. | |
370 | * @see java.lang.String#valueOf(long) | |
371 | */ | |
ee9dd372 | 372 | public StringBuffer insert (int offset, long lnum) |
2238de65 TT |
373 | { |
374 | return insert (offset, String.valueOf(lnum)); | |
375 | } | |
376 | ||
377 | /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
378 | * Uses <code>String.valueOf()</code> to convert to | |
379 | * <code>String</code>. | |
380 | * @param offset the place to insert. | |
381 | * @param fnum the <code>float</code> to convert and insert. | |
382 | * @return this <code>StringBuffer</code>. | |
383 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
384 | * of range for this <code>StringBuffer</code>. | |
385 | * @see java.lang.String#valueOf(float) | |
386 | */ | |
ee9dd372 | 387 | public StringBuffer insert (int offset, float fnum) |
2238de65 TT |
388 | { |
389 | return insert (offset, String.valueOf(fnum)); | |
390 | } | |
391 | ||
392 | /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
393 | * Uses <code>String.valueOf()</code> to convert to | |
394 | * <code>String</code>. | |
395 | * @param offset the place to insert. | |
396 | * @param dnum the <code>double</code> to convert and insert. | |
397 | * @return this <code>StringBuffer</code>. | |
398 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
399 | * of range for this <code>StringBuffer</code>. | |
400 | * @see java.lang.String#valueOf(double) | |
401 | */ | |
ee9dd372 | 402 | public StringBuffer insert (int offset, double dnum) |
2238de65 TT |
403 | { |
404 | return insert (offset, String.valueOf(dnum)); | |
405 | } | |
406 | ||
407 | /** Insert the <code>String</code> value of the argument into this <code>StringBuffer</code>. | |
408 | * Uses <code>String.valueOf()</code> to convert to | |
409 | * <code>String</code>. | |
410 | * @param offset the place to insert. | |
411 | * @param obj the <code>Object</code> to convert and insert. | |
412 | * @return this <code>StringBuffer</code>. | |
413 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
414 | * of range for this <code>StringBuffer</code>. | |
415 | * @see java.lang.String#valueOf(java.lang.Object) | |
416 | */ | |
ee9dd372 | 417 | public StringBuffer insert (int offset, Object obj) |
2238de65 TT |
418 | { |
419 | return insert (offset, String.valueOf(obj)); | |
420 | } | |
421 | ||
422 | /** Insert the <code>String</code> argument into this <code>StringBuffer</code>. | |
423 | * @param offset the place to insert. | |
424 | * @param str the <code>String</code> to insert. | |
425 | * @return this <code>StringBuffer</code>. | |
426 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
427 | * of range for this <code>StringBuffer</code>. | |
428 | */ | |
ee9dd372 | 429 | public synchronized StringBuffer insert (int offset, String str) |
2238de65 TT |
430 | { |
431 | if (offset < 0 || offset > count) | |
432 | throw new StringIndexOutOfBoundsException (offset); | |
433 | // Note that using `null' is from JDK 1.2. | |
434 | if (str == null) | |
435 | str = "null"; | |
436 | int len = str.length(); | |
437 | ensureCapacity_unsynchronized (count+len); | |
438 | System.arraycopy(value, offset, value, offset+len, count-offset); | |
439 | str.getChars(0, len, value, offset); | |
440 | count += len; | |
441 | return this; | |
442 | } | |
443 | ||
444 | /** Insert the <code>char[]</code> argument into this | |
445 | * <code>StringBuffer</code>. | |
446 | * @param offset the place to insert. | |
447 | * @param data the <code>char[]</code> to insert. | |
448 | * @return this <code>StringBuffer</code>. | |
449 | * @exception NullPointerException if <code>data</code> is | |
450 | * <code>null</code>. | |
451 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
452 | * of range for this <code>StringBuffer</code>. | |
453 | */ | |
454 | public StringBuffer insert (int offset, char[] data) | |
455 | { | |
456 | return insert (offset, data, 0, data.length); | |
457 | } | |
458 | ||
459 | /** Insert the <code>char[]</code> argument into this | |
460 | * <code>StringBuffer</code>. | |
461 | * @param offset the place to insert. | |
462 | * @param str the <code>char[]</code> to insert. | |
463 | * @param str_offset the index in <code>str</code> to start inserting | |
464 | * from. | |
465 | * @param len the number of characters to insert. | |
466 | * @return this <code>StringBuffer</code>. | |
467 | * @exception NullPointerException if <code>str</code> is <code>null</code>. | |
468 | * @exception IndexOutOfBoundsException if <code>offset</code> is out | |
469 | * of range, for this <code>StringBuffer</code>, or if | |
470 | * <code>str_offset</code> or <code>str_offset+len</code> | |
471 | * are out of range for <code>str</code>. | |
472 | */ | |
473 | public synchronized StringBuffer insert(int offset, char[] str, | |
474 | int str_offset, int len) | |
475 | { | |
476 | if (offset < 0 || offset > count) | |
477 | throw new StringIndexOutOfBoundsException (offset); | |
478 | if (len < 0) | |
479 | throw new StringIndexOutOfBoundsException (len); | |
480 | if (str_offset < 0 || str_offset + len > str.length) | |
481 | throw new StringIndexOutOfBoundsException (str_offset); | |
482 | ensureCapacity_unsynchronized (count + len); | |
483 | System.arraycopy(value, offset, value, offset + len, count - offset); | |
484 | System.arraycopy(str, str_offset, value, offset, len); | |
485 | count += len; | |
486 | return this; | |
487 | } | |
488 | ||
489 | /** Get the length of the <code>String</code> this | |
490 | * <code>StringBuffer</code> would create. Not to be confused with the | |
491 | * <em>capacity</em> of the <code>StringBuffer</code>. | |
492 | * @return the length of this <code>StringBuffer</code>. | |
493 | * @see #capacity() | |
494 | * @see #setLength() | |
495 | */ | |
ee9dd372 | 496 | public int length () |
2238de65 TT |
497 | { |
498 | return count; | |
499 | } | |
500 | ||
501 | /** Delete a character from this <code>StringBuffer</code>. | |
502 | * @param index the index of the character to delete. | |
503 | * @return this <code>StringBuffer</code>. | |
504 | * @exception StringIndexOutOfBoundsException if <code>index</code> | |
505 | * is out of bounds. | |
506 | */ | |
507 | public synchronized StringBuffer replace (int start, int end, String str) | |
508 | { | |
509 | // FIXME: this is inefficient. | |
510 | delete (start, end); | |
511 | return insert (start, str); | |
512 | } | |
513 | ||
514 | /** Reverse the characters in this StringBuffer. | |
515 | * @return this <code>StringBuffer</code>. | |
516 | */ | |
ee9dd372 | 517 | public synchronized StringBuffer reverse () |
2238de65 TT |
518 | { |
519 | for (int i = 0; i < count / 2; ++i) | |
520 | { | |
521 | char c = value[i]; | |
522 | value[i] = value[count - i - 1]; | |
523 | value[count - i - 1] = c; | |
524 | } | |
525 | return this; | |
526 | } | |
527 | ||
528 | /** Set the character at the specified index. | |
529 | * @param index the index of the character to set starting at 0. | |
530 | * @param ch the value to set that character to. | |
531 | * @exception IndexOutOfBoundsException if the specified character | |
532 | * index is not between 0 and length() - 1 (inclusive). | |
533 | */ | |
ee9dd372 | 534 | public synchronized void setCharAt (int index, char ch) |
2238de65 TT |
535 | { |
536 | if (index < 0 || index >= count) | |
537 | throw new StringIndexOutOfBoundsException (index); | |
538 | // Call ensureCapacity to enforce copy-on-write. | |
539 | ensureCapacity_unsynchronized (count); | |
540 | value[index] = ch; | |
541 | } | |
542 | ||
543 | /** Set the length of this StringBuffer. | |
544 | * <P> | |
545 | * If the new length is greater than the current length, all the new | |
546 | * characters are set to '\0'. | |
547 | * <P> | |
548 | * If the new length is less than the current length, the first | |
549 | * <code>newLength</code> characters of the old array will be | |
550 | * @param newLength the new length | |
551 | * @exception IndexOutOfBoundsException if the new length is | |
552 | * negative. | |
553 | * @see #length() | |
554 | */ | |
ee9dd372 | 555 | public synchronized void setLength (int newLength) |
2238de65 TT |
556 | { |
557 | if (newLength < 0) | |
558 | throw new StringIndexOutOfBoundsException (newLength); | |
559 | ||
560 | ensureCapacity_unsynchronized (newLength); | |
561 | for (int i = count; i < newLength; ++i) | |
562 | value[i] = '\0'; | |
563 | count = newLength; | |
564 | } | |
565 | ||
566 | /** Create a new StringBuffer with default capacity 16. | |
567 | * @see JLS 20.13.1 | |
568 | */ | |
ee9dd372 | 569 | public StringBuffer () |
2238de65 TT |
570 | { |
571 | this (DEFAULT_CAPACITY); | |
572 | } | |
ee9dd372 | 573 | |
2238de65 TT |
574 | /** Create an empty <code>StringBuffer</code> with the specified initial capacity. |
575 | * @param capacity the initial capacity. | |
576 | */ | |
ee9dd372 | 577 | public StringBuffer (int capacity) |
2238de65 TT |
578 | { |
579 | count = 0; | |
580 | value = new char[capacity]; | |
581 | shared = false; | |
582 | } | |
583 | ||
584 | /** Create a new <code>StringBuffer</code> with the characters in the specified <code>String</code>. | |
585 | * Initial capacity will be the size of the String plus 16. | |
586 | * @param str the <code>String</code> to make a <code>StringBuffer</code> out of. | |
587 | * @XXX optimize for sharing. | |
588 | */ | |
ee9dd372 | 589 | public StringBuffer (String str) |
2238de65 TT |
590 | { |
591 | // The documentation is not clear, but experimentation with | |
592 | // other implementations indicates that StringBuffer(null) | |
593 | // should throw a NullPointerException. | |
594 | count = str.length(); | |
595 | // JLS: The initial capacity of the string buffer is 16 plus the | |
596 | // length of the argument string. | |
597 | value = new char[count + 16]; | |
598 | str.getChars(0, count, value, 0); | |
599 | shared = false; | |
600 | } | |
601 | ||
602 | /** | |
603 | * Creates a substring of this StringBuffer, starting at a specified index | |
604 | * and ending at the end of this StringBuffer. | |
605 | * | |
606 | * @param beginIndex index to start substring (base 0) | |
607 | * | |
608 | * @return new String which is a substring of this StringBuffer | |
609 | * | |
610 | * @exception StringIndexOutOfBoundsException | |
611 | * if (beginIndex < 0 || beginIndex > this.length()) | |
612 | */ | |
613 | public String substring (int beginIndex) | |
614 | { | |
615 | return substring (beginIndex, count); | |
616 | } | |
617 | ||
618 | /** | |
619 | * Creates a substring of this StringBuffer, starting at a specified index | |
620 | * and ending at one character before a specified index. | |
621 | * | |
622 | * @param beginIndex index to start substring (base 0) | |
623 | * @param endIndex index after the last character to be | |
624 | * copied into the substring | |
625 | * | |
626 | * @return new String which is a substring of this StringBuffer | |
627 | * | |
628 | * @exception StringIndexOutOfBoundsException | |
629 | * if (beginIndex < 0 || endIndex > this.length() || beginIndex > endIndex) | |
630 | */ | |
631 | public synchronized String substring (int beginIndex, int endIndex) | |
632 | { | |
633 | if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) | |
634 | throw new StringIndexOutOfBoundsException (); | |
635 | // FIXME: for libgcj it would be possible, and more efficient, to | |
636 | // enable sharing here. | |
637 | return new String (value, beginIndex, endIndex - beginIndex); | |
638 | } | |
639 | ||
640 | /** Convert this <code>StringBuffer</code> to a <code>String</code>. | |
641 | * @return the characters in this StringBuffer | |
642 | */ | |
ee9dd372 | 643 | public String toString () |
2238de65 TT |
644 | { |
645 | // Note: in libgcj this causes the StringBuffer to be shared. In | |
646 | // Classpath it does not. | |
647 | return new String (this); | |
648 | } | |
ee9dd372 TT |
649 | |
650 | // Index of next available character. Note that this has | |
651 | // permissions set this way so that String can get the value. | |
652 | int count; | |
653 | ||
2238de65 TT |
654 | // The buffer. Note that this has permissions set this way so that |
655 | // String can get the value. | |
656 | char[] value; | |
657 | ||
ee9dd372 TT |
658 | // True if we need to copy the buffer before writing to it again. |
659 | // FIXME: JDK 1.2 doesn't specify this. The new buffer-growing | |
2238de65 TT |
660 | // semantics make this less useful in that case, too. Note that |
661 | // this has permissions set this way so that String can get the | |
662 | // value. | |
663 | boolean shared; | |
664 | ||
665 | static final long serialVersionUID = 3388685877147921107L; | |
666 | private final static int DEFAULT_CAPACITY = 16; // JLS 20.13.1 | |
ee9dd372 | 667 | } |