OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [lang/] [StringBuffer.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* StringBuffer.java -- Growable strings
2
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
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)
10
any later version.
11
 
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.
16
 
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
20
02110-1301 USA.
21
 
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
25
combination.
26
 
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. */
38
 
39
package java.lang;
40
 
41
import java.io.Serializable;
42
 
43
/**
44
 * <code>StringBuffer</code> represents a changeable <code>String</code>.
45
 * It provides the operations required to modify the
46
 * <code>StringBuffer</code>, including insert, replace, delete, append,
47
 * and reverse. It is thread-safe; meaning that all modifications to a buffer
48
 * are in synchronized methods.
49
 *
50
 * <p><code>StringBuffer</code>s are variable-length in nature, so even if
51
 * you initialize them to a certain size, they can still grow larger than
52
 * that. <em>Capacity</em> indicates the number of characters the
53
 * <code>StringBuffer</code> can have in it before it has to grow (growing
54
 * the char array is an expensive operation involving <code>new</code>).
55
 *
56
 * <p>Incidentally, compilers often implement the String operator "+"
57
 * by using a <code>StringBuffer</code> operation:<br>
58
 * <code>a + b</code><br>
59
 * is the same as<br>
60
 * <code>new StringBuffer().append(a).append(b).toString()</code>.
61
 *
62
 * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
63
 * efficiency.  This will help when a StringBuffer is converted to a String
64
 * and the StringBuffer is not changed after that (quite common when performing
65
 * string concatenation).
66
 *
67
 * @author Paul Fisher
68
 * @author John Keiser
69
 * @author Tom Tromey
70
 * @author Eric Blake (ebb9@email.byu.edu)
71
 * @see String
72
 * @since 1.0
73
 * @status updated to 1.4
74
 */
75
public final class StringBuffer implements Serializable, CharSequence
76
{
77
  /**
78
   * Compatible with JDK 1.0+.
79
   */
80
  private static final long serialVersionUID = 3388685877147921107L;
81
 
82
  /**
83
   * Index of next available character (and thus the size of the current
84
   * string contents).  Note that this has permissions set this way so that
85
   * String can get the value.
86
   *
87
   * @serial the number of characters in the buffer
88
   */
89
  int count;
90
 
91
  /**
92
   * The buffer.  Note that this has permissions set this way so that String
93
   * can get the value.
94
   *
95
   * @serial the buffer
96
   */
97
  char[] value;
98
 
99
  /**
100
   * True if the buffer is shared with another object (StringBuffer or
101
   * String); this means the buffer must be copied before writing to it again.
102
   * Note that this has permissions set this way so that String can get the
103
   * value.
104
   *
105
   * @serial whether the buffer is shared
106
   */
107
  boolean shared;
108
 
109
  /**
110
   * The default capacity of a buffer.
111
   */
112
  private static final int DEFAULT_CAPACITY = 16;
113
 
114
  /**
115
   * Create a new StringBuffer with default capacity 16.
116
   */
117
  public StringBuffer()
118
  {
119
    this(DEFAULT_CAPACITY);
120
  }
121
 
122
  /**
123
   * Create an empty <code>StringBuffer</code> with the specified initial
124
   * capacity.
125
   *
126
   * @param capacity the initial capacity
127
   * @throws NegativeArraySizeException if capacity is negative
128
   */
129
  public StringBuffer(int capacity)
130
  {
131
    value = new char[capacity];
132
  }
133
 
134
  /**
135
   * Create a new <code>StringBuffer</code> with the characters in the
136
   * specified <code>String</code>. Initial capacity will be the size of the
137
   * String plus 16.
138
   *
139
   * @param str the <code>String</code> to convert
140
   * @throws NullPointerException if str is null
141
   */
142
  public StringBuffer(String str)
143
  {
144
    // Unfortunately, because the size is 16 larger, we cannot share.
145
    count = str.count;
146
    value = new char[count + DEFAULT_CAPACITY];
147
    str.getChars(0, count, value, 0);
148
  }
149
 
150
  /**
151
   * Create a new <code>StringBuffer</code> with the characters from the
152
   * specified <code>CharSequence</code>. Initial capacity will be the
153
   * size of the CharSequence plus 16.
154
   *
155
   * @param sequence the <code>String</code> to convert
156
   * @throws NullPointerException if str is null
157
   *
158
   * @since 1.5
159
   */
160
  public StringBuffer(CharSequence sequence)
161
  {
162
    count = Math.max(0, sequence.length());
163
    value = new char[count + DEFAULT_CAPACITY];
164
    for (int i = 0; i < count; ++i)
165
      value[i] = sequence.charAt(i);
166
  }
167
 
168
  /**
169
   * Get the length of the <code>String</code> this <code>StringBuffer</code>
170
   * would create. Not to be confused with the <em>capacity</em> of the
171
   * <code>StringBuffer</code>.
172
   *
173
   * @return the length of this <code>StringBuffer</code>
174
   * @see #capacity()
175
   * @see #setLength(int)
176
   */
177
  public synchronized int length()
178
  {
179
    return count;
180
  }
181
 
182
  /**
183
   * Get the total number of characters this <code>StringBuffer</code> can
184
   * support before it must be grown.  Not to be confused with <em>length</em>.
185
   *
186
   * @return the capacity of this <code>StringBuffer</code>
187
   * @see #length()
188
   * @see #ensureCapacity(int)
189
   */
190
  public synchronized int capacity()
191
  {
192
    return value.length;
193
  }
194
 
195
  /**
196
   * Increase the capacity of this <code>StringBuffer</code>. This will
197
   * ensure that an expensive growing operation will not occur until
198
   * <code>minimumCapacity</code> is reached. The buffer is grown to the
199
   * larger of <code>minimumCapacity</code> and
200
   * <code>capacity() * 2 + 2</code>, if it is not already large enough.
201
   *
202
   * @param minimumCapacity the new capacity
203
   * @see #capacity()
204
   */
205
  public synchronized void ensureCapacity(int minimumCapacity)
206
  {
207
    ensureCapacity_unsynchronized(minimumCapacity);
208
  }
209
 
210
  /**
211
   * Set the length of this StringBuffer. If the new length is greater than
212
   * the current length, all the new characters are set to '\0'. If the new
213
   * length is less than the current length, the first <code>newLength</code>
214
   * characters of the old array will be preserved, and the remaining
215
   * characters are truncated.
216
   *
217
   * @param newLength the new length
218
   * @throws IndexOutOfBoundsException if the new length is negative
219
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
220
   * @see #length()
221
   */
222
  public synchronized void setLength(int newLength)
223
  {
224
    if (newLength < 0)
225
      throw new StringIndexOutOfBoundsException(newLength);
226
 
227
    int valueLength = value.length;
228
 
229
    /* Always call ensureCapacity_unsynchronized in order to preserve
230
       copy-on-write semantics.  */
231
    ensureCapacity_unsynchronized(newLength);
232
 
233
    if (newLength < valueLength)
234
      {
235
        /* If the StringBuffer's value just grew, then we know that
236
           value is newly allocated and the region between count and
237
           newLength is filled with '\0'.  */
238
        count = newLength;
239
      }
240
    else
241
      {
242
        /* The StringBuffer's value doesn't need to grow.  However,
243
           we should clear out any cruft that may exist.  */
244
        while (count < newLength)
245
          value[count++] = '\0';
246
      }
247
  }
248
 
249
  /**
250
   * Get the character at the specified index.
251
   *
252
   * @param index the index of the character to get, starting at 0
253
   * @return the character at the specified index
254
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
255
   */
256
  public synchronized char charAt(int index)
257
  {
258
    if (index < 0 || index >= count)
259
      throw new StringIndexOutOfBoundsException(index);
260
    return value[index];
261
  }
262
 
263
  /**
264
   * Get the code point at the specified index.  This is like #charAt(int),
265
   * but if the character is the start of a surrogate pair, and the
266
   * following character completes the pair, then the corresponding
267
   * supplementary code point is returned.
268
   * @param index the index of the codepoint to get, starting at 0
269
   * @return the codepoint at the specified index
270
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
271
   * @since 1.5
272
   */
273
  public synchronized int codePointAt(int index)
274
  {
275
    return Character.codePointAt(value, index, count);
276
  }
277
 
278
  /**
279
   * Get the code point before the specified index.  This is like
280
   * #codePointAt(int), but checks the characters at <code>index-1</code> and
281
   * <code>index-2</code> to see if they form a supplementary code point.
282
   * @param index the index just past the codepoint to get, starting at 0
283
   * @return the codepoint at the specified index
284
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
285
   * @since 1.5
286
   */
287
  public synchronized int codePointBefore(int index)
288
  {
289
    // Character.codePointBefore() doesn't perform this check.  We
290
    // could use the CharSequence overload, but this is just as easy.
291
    if (index >= count)
292
      throw new IndexOutOfBoundsException();
293
    return Character.codePointBefore(value, index, 1);
294
  }
295
 
296
  /**
297
   * Get the specified array of characters. <code>srcOffset - srcEnd</code>
298
   * characters will be copied into the array you pass in.
299
   *
300
   * @param srcOffset the index to start copying from (inclusive)
301
   * @param srcEnd the index to stop copying from (exclusive)
302
   * @param dst the array to copy into
303
   * @param dstOffset the index to start copying into
304
   * @throws NullPointerException if dst is null
305
   * @throws IndexOutOfBoundsException if any source or target indices are
306
   *         out of range (while unspecified, source problems cause a
307
   *         StringIndexOutOfBoundsException, and dest problems cause an
308
   *         ArrayIndexOutOfBoundsException)
309
   * @see System#arraycopy(Object, int, Object, int, int)
310
   */
311
  public synchronized void getChars(int srcOffset, int srcEnd,
312
                                    char[] dst, int dstOffset)
313
  {
314
    if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
315
      throw new StringIndexOutOfBoundsException();
316
    VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
317
  }
318
 
319
  /**
320
   * Set the character at the specified index.
321
   *
322
   * @param index the index of the character to set starting at 0
323
   * @param ch the value to set that character to
324
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
325
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
326
   */
327
  public synchronized void setCharAt(int index, char ch)
328
  {
329
    if (index < 0 || index >= count)
330
      throw new StringIndexOutOfBoundsException(index);
331
    // Call ensureCapacity to enforce copy-on-write.
332
    ensureCapacity_unsynchronized(count);
333
    value[index] = ch;
334
  }
335
 
336
  /**
337
   * Append the <code>String</code> value of the argument to this
338
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
339
   * to <code>String</code>.
340
   *
341
   * @param obj the <code>Object</code> to convert and append
342
   * @return this <code>StringBuffer</code>
343
   * @see String#valueOf(Object)
344
   * @see #append(String)
345
   */
346
  public StringBuffer append(Object obj)
347
  {
348
    return append(obj == null ? "null" : obj.toString());
349
  }
350
 
351
  /**
352
   * Append the <code>String</code> to this <code>StringBuffer</code>. If
353
   * str is null, the String "null" is appended.
354
   *
355
   * @param str the <code>String</code> to append
356
   * @return this <code>StringBuffer</code>
357
   */
358
  public synchronized StringBuffer append(String str)
359
  {
360
    if (str == null)
361
      str = "null";
362
    int len = str.count;
363
    ensureCapacity_unsynchronized(count + len);
364
    str.getChars(0, len, value, count);
365
    count += len;
366
    return this;
367
  }
368
 
369
  /**
370
   * Append the <code>StringBuffer</code> value of the argument to this
371
   * <code>StringBuffer</code>. This behaves the same as
372
   * <code>append((Object) stringBuffer)</code>, except it is more efficient.
373
   *
374
   * @param stringBuffer the <code>StringBuffer</code> to convert and append
375
   * @return this <code>StringBuffer</code>
376
   * @see #append(Object)
377
   * @since 1.4
378
   */
379
  public synchronized StringBuffer append(StringBuffer stringBuffer)
380
  {
381
    if (stringBuffer == null)
382
      return append("null");
383
    synchronized (stringBuffer)
384
      {
385
        int len = stringBuffer.count;
386
        ensureCapacity_unsynchronized(count + len);
387
        VMSystem.arraycopy(stringBuffer.value, 0, value, count, len);
388
        count += len;
389
      }
390
    return this;
391
  }
392
 
393
  /**
394
   * Append the <code>CharSequence</code> value of the argument to this
395
   * <code>StringBuffer</code>.
396
   *
397
   * @param sequence the <code>CharSequence</code> to append
398
   * @return this <code>StringBuffer</code>
399
   * @see #append(Object)
400
   * @since 1.5
401
   */
402
  public synchronized StringBuffer append(CharSequence sequence)
403
  {
404
    if (sequence == null)
405
      sequence = "null";
406
    return append(sequence, 0, sequence.length());
407
  }
408
 
409
  /**
410
   * Append the specified subsequence of the <code>CharSequence</code>
411
   * argument to this <code>StringBuffer</code>.
412
   *
413
   * @param sequence the <code>CharSequence</code> to append
414
   * @param start the starting index
415
   * @param end one past the ending index
416
   * @return this <code>StringBuffer</code>
417
   * @see #append(Object)
418
   * @since 1.5
419
   */
420
  public synchronized StringBuffer append(CharSequence sequence,
421
                                          int start, int end)
422
  {
423
    if (sequence == null)
424
      sequence = "null";
425
    if (start < 0 || end < 0 || start > end || end > sequence.length())
426
      throw new IndexOutOfBoundsException();
427
    ensureCapacity_unsynchronized(this.count + end - start);
428
    for (int i = start; i < end; ++i)
429
      value[count++] = sequence.charAt(i);
430
    return this;
431
  }
432
 
433
  /**
434
   * Append the <code>char</code> array to this <code>StringBuffer</code>.
435
   * This is similar (but more efficient) than
436
   * <code>append(new String(data))</code>, except in the case of null.
437
   *
438
   * @param data the <code>char[]</code> to append
439
   * @return this <code>StringBuffer</code>
440
   * @throws NullPointerException if <code>str</code> is <code>null</code>
441
   * @see #append(char[], int, int)
442
   */
443
  public StringBuffer append(char[] data)
444
  {
445
    return append(data, 0, data.length);
446
  }
447
 
448
  /**
449
   * Append part of the <code>char</code> array to this
450
   * <code>StringBuffer</code>. This is similar (but more efficient) than
451
   * <code>append(new String(data, offset, count))</code>, except in the case
452
   * of null.
453
   *
454
   * @param data the <code>char[]</code> to append
455
   * @param offset the start location in <code>str</code>
456
   * @param count the number of characters to get from <code>str</code>
457
   * @return this <code>StringBuffer</code>
458
   * @throws NullPointerException if <code>str</code> is <code>null</code>
459
   * @throws IndexOutOfBoundsException if offset or count is out of range
460
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
461
   */
462
  public synchronized StringBuffer append(char[] data, int offset, int count)
463
  {
464
    if (offset < 0 || count < 0 || offset > data.length - count)
465
      throw new StringIndexOutOfBoundsException();
466
    ensureCapacity_unsynchronized(this.count + count);
467
    VMSystem.arraycopy(data, offset, value, this.count, count);
468
    this.count += count;
469
    return this;
470
  }
471
 
472
  /**
473
   * Append the <code>String</code> value of the argument to this
474
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
475
   * to <code>String</code>.
476
   *
477
   * @param bool the <code>boolean</code> to convert and append
478
   * @return this <code>StringBuffer</code>
479
   * @see String#valueOf(boolean)
480
   */
481
  public StringBuffer append(boolean bool)
482
  {
483
    return append(bool ? "true" : "false");
484
  }
485
 
486
  /**
487
   * Append the <code>char</code> to this <code>StringBuffer</code>.
488
   *
489
   * @param ch the <code>char</code> to append
490
   * @return this <code>StringBuffer</code>
491
   */
492
  public synchronized StringBuffer append(char ch)
493
  {
494
    ensureCapacity_unsynchronized(count + 1);
495
    value[count++] = ch;
496
    return this;
497
  }
498
 
499
  /**
500
   * Append the code point to this <code>StringBuffer</code>.
501
   * This is like #append(char), but will append two characters
502
   * if a supplementary code point is given.
503
   *
504
   * @param code the code point to append
505
   * @return this <code>StringBuffer</code>
506
   * @see Character#toChars(int, char[], int)
507
   * @since 1.5
508
   */
509
  public synchronized StringBuffer appendCodePoint(int code)
510
  {
511
    int len = Character.charCount(code);
512
    ensureCapacity_unsynchronized(count + len);
513
    Character.toChars(code, value, count);
514
    count += len;
515
    return this;
516
  }
517
 
518
  /**
519
   * Append the <code>String</code> value of the argument to this
520
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
521
   * to <code>String</code>.
522
   *
523
   * @param inum the <code>int</code> to convert and append
524
   * @return this <code>StringBuffer</code>
525
   * @see String#valueOf(int)
526
   */
527
  // This is native in libgcj, for efficiency.
528
  public StringBuffer append(int inum)
529
  {
530
    return append(String.valueOf(inum));
531
  }
532
 
533
  /**
534
   * Append the <code>String</code> value of the argument to this
535
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
536
   * to <code>String</code>.
537
   *
538
   * @param lnum the <code>long</code> to convert and append
539
   * @return this <code>StringBuffer</code>
540
   * @see String#valueOf(long)
541
   */
542
  public StringBuffer append(long lnum)
543
  {
544
    return append(Long.toString(lnum, 10));
545
  }
546
 
547
  /**
548
   * Append the <code>String</code> value of the argument to this
549
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
550
   * to <code>String</code>.
551
   *
552
   * @param fnum the <code>float</code> to convert and append
553
   * @return this <code>StringBuffer</code>
554
   * @see String#valueOf(float)
555
   */
556
  public StringBuffer append(float fnum)
557
  {
558
    return append(Float.toString(fnum));
559
  }
560
 
561
  /**
562
   * Append the <code>String</code> value of the argument to this
563
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
564
   * to <code>String</code>.
565
   *
566
   * @param dnum the <code>double</code> to convert and append
567
   * @return this <code>StringBuffer</code>
568
   * @see String#valueOf(double)
569
   */
570
  public StringBuffer append(double dnum)
571
  {
572
    return append(Double.toString(dnum));
573
  }
574
 
575
  /**
576
   * Delete characters from this <code>StringBuffer</code>.
577
   * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
578
   * harmless for end to be larger than length().
579
   *
580
   * @param start the first character to delete
581
   * @param end the index after the last character to delete
582
   * @return this <code>StringBuffer</code>
583
   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
584
   * @since 1.2
585
   */
586
  public synchronized StringBuffer delete(int start, int end)
587
  {
588
    if (start < 0 || start > count || start > end)
589
      throw new StringIndexOutOfBoundsException(start);
590
    if (end > count)
591
      end = count;
592
    // This will unshare if required.
593
    ensureCapacity_unsynchronized(count);
594
    if (count - end != 0)
595
      VMSystem.arraycopy(value, end, value, start, count - end);
596
    count -= end - start;
597
    return this;
598
  }
599
 
600
  /**
601
   * Delete a character from this <code>StringBuffer</code>.
602
   *
603
   * @param index the index of the character to delete
604
   * @return this <code>StringBuffer</code>
605
   * @throws StringIndexOutOfBoundsException if index is out of bounds
606
   * @since 1.2
607
   */
608
  public StringBuffer deleteCharAt(int index)
609
  {
610
    return delete(index, index + 1);
611
  }
612
 
613
  /**
614
   * Replace characters between index <code>start</code> (inclusive) and
615
   * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
616
   * is larger than the size of this StringBuffer, all characters after
617
   * <code>start</code> are replaced.
618
   *
619
   * @param start the beginning index of characters to delete (inclusive)
620
   * @param end the ending index of characters to delete (exclusive)
621
   * @param str the new <code>String</code> to insert
622
   * @return this <code>StringBuffer</code>
623
   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
624
   * @throws NullPointerException if str is null
625
   * @since 1.2
626
   */
627
  public synchronized StringBuffer replace(int start, int end, String str)
628
  {
629
    if (start < 0 || start > count || start > end)
630
      throw new StringIndexOutOfBoundsException(start);
631
 
632
    int len = str.count;
633
    // Calculate the difference in 'count' after the replace.
634
    int delta = len - (end > count ? count : end) + start;
635
    ensureCapacity_unsynchronized(count + delta);
636
 
637
    if (delta != 0 && end < count)
638
      VMSystem.arraycopy(value, end, value, end + delta, count - end);
639
 
640
    str.getChars(0, len, value, start);
641
    count += delta;
642
    return this;
643
  }
644
 
645
  /**
646
   * Creates a substring of this StringBuffer, starting at a specified index
647
   * and ending at the end of this StringBuffer.
648
   *
649
   * @param beginIndex index to start substring (base 0)
650
   * @return new String which is a substring of this StringBuffer
651
   * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
652
   * @see #substring(int, int)
653
   * @since 1.2
654
   */
655
  public String substring(int beginIndex)
656
  {
657
    return substring(beginIndex, count);
658
  }
659
 
660
  /**
661
   * Creates a substring of this StringBuffer, starting at a specified index
662
   * and ending at one character before a specified index. This is implemented
663
   * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
664
   * the CharSequence interface.
665
   *
666
   * @param beginIndex index to start at (inclusive, base 0)
667
   * @param endIndex index to end at (exclusive)
668
   * @return new String which is a substring of this StringBuffer
669
   * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
670
   *         bounds
671
   * @see #substring(int, int)
672
   * @since 1.4
673
   */
674
  public CharSequence subSequence(int beginIndex, int endIndex)
675
  {
676
    return substring(beginIndex, endIndex);
677
  }
678
 
679
  /**
680
   * Creates a substring of this StringBuffer, starting at a specified index
681
   * and ending at one character before a specified index.
682
   *
683
   * @param beginIndex index to start at (inclusive, base 0)
684
   * @param endIndex index to end at (exclusive)
685
   * @return new String which is a substring of this StringBuffer
686
   * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
687
   *         of bounds
688
   * @since 1.2
689
   */
690
  public synchronized String substring(int beginIndex, int endIndex)
691
  {
692
    int len = endIndex - beginIndex;
693
    if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
694
      throw new StringIndexOutOfBoundsException();
695
    if (len == 0)
696
      return "";
697
    // Don't copy unless substring is smaller than 1/4 of the buffer.
698
    boolean share_buffer = ((len << 2) >= value.length);
699
    if (share_buffer)
700
      this.shared = true;
701
    // Package constructor avoids an array copy.
702
    return new String(value, beginIndex, len, share_buffer);
703
  }
704
 
705
  /**
706
   * Insert a subarray of the <code>char[]</code> argument into this
707
   * <code>StringBuffer</code>.
708
   *
709
   * @param offset the place to insert in this buffer
710
   * @param str the <code>char[]</code> to insert
711
   * @param str_offset the index in <code>str</code> to start inserting from
712
   * @param len the number of characters to insert
713
   * @return this <code>StringBuffer</code>
714
   * @throws NullPointerException if <code>str</code> is <code>null</code>
715
   * @throws StringIndexOutOfBoundsException if any index is out of bounds
716
   * @since 1.2
717
   */
718
  public synchronized StringBuffer insert(int offset,
719
                                          char[] str, int str_offset, int len)
720
  {
721
    if (offset < 0 || offset > count || len < 0
722
        || str_offset < 0 || str_offset > str.length - len)
723
      throw new StringIndexOutOfBoundsException();
724
    ensureCapacity_unsynchronized(count + len);
725
    VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
726
    VMSystem.arraycopy(str, str_offset, value, offset, len);
727
    count += len;
728
    return this;
729
  }
730
 
731
  /**
732
   * Insert the <code>String</code> value of the argument into this
733
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
734
   * to <code>String</code>.
735
   *
736
   * @param offset the place to insert in this buffer
737
   * @param obj the <code>Object</code> to convert and insert
738
   * @return this <code>StringBuffer</code>
739
   * @exception StringIndexOutOfBoundsException if offset is out of bounds
740
   * @see String#valueOf(Object)
741
   */
742
  public StringBuffer insert(int offset, Object obj)
743
  {
744
    return insert(offset, obj == null ? "null" : obj.toString());
745
  }
746
 
747
  /**
748
   * Insert the <code>String</code> argument into this
749
   * <code>StringBuffer</code>. If str is null, the String "null" is used
750
   * instead.
751
   *
752
   * @param offset the place to insert in this buffer
753
   * @param str the <code>String</code> to insert
754
   * @return this <code>StringBuffer</code>
755
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
756
   */
757
  public synchronized StringBuffer insert(int offset, String str)
758
  {
759
    if (offset < 0 || offset > count)
760
      throw new StringIndexOutOfBoundsException(offset);
761
    if (str == null)
762
      str = "null";
763
    int len = str.count;
764
    ensureCapacity_unsynchronized(count + len);
765
    VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
766
    str.getChars(0, len, value, offset);
767
    count += len;
768
    return this;
769
  }
770
 
771
  /**
772
   * Insert the <code>CharSequence</code> argument into this
773
   * <code>StringBuffer</code>.  If the sequence is null, the String
774
   * "null" is used instead.
775
   *
776
   * @param offset the place to insert in this buffer
777
   * @param sequence the <code>CharSequence</code> to insert
778
   * @return this <code>StringBuffer</code>
779
   * @throws IndexOutOfBoundsException if offset is out of bounds
780
   * @since 1.5
781
   */
782
  public synchronized StringBuffer insert(int offset, CharSequence sequence)
783
  {
784
    if (sequence == null)
785
      sequence = "null";
786
    return insert(offset, sequence, 0, sequence.length());
787
  }
788
 
789
  /**
790
   * Insert a subsequence of the <code>CharSequence</code> argument into this
791
   * <code>StringBuffer</code>.  If the sequence is null, the String
792
   * "null" is used instead.
793
   *
794
   * @param offset the place to insert in this buffer
795
   * @param sequence the <code>CharSequence</code> to insert
796
   * @param start the starting index of the subsequence
797
   * @param end one past the ending index of the subsequence
798
   * @return this <code>StringBuffer</code>
799
   * @throws IndexOutOfBoundsException if offset, start,
800
   * or end are out of bounds
801
   * @since 1.5
802
   */
803
  public synchronized StringBuffer insert(int offset, CharSequence sequence,
804
                                          int start, int end)
805
  {
806
    if (sequence == null)
807
      sequence = "null";
808
    if (start < 0 || end < 0 || start > end || end > sequence.length())
809
      throw new IndexOutOfBoundsException();
810
    int len = end - start;
811
    ensureCapacity_unsynchronized(count + len);
812
    VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
813
    for (int i = start; i < end; ++i)
814
      value[offset++] = sequence.charAt(i);
815
    count += len;
816
    return this;
817
  }
818
 
819
  /**
820
   * Insert the <code>char[]</code> argument into this
821
   * <code>StringBuffer</code>.
822
   *
823
   * @param offset the place to insert in this buffer
824
   * @param data the <code>char[]</code> to insert
825
   * @return this <code>StringBuffer</code>
826
   * @throws NullPointerException if <code>data</code> is <code>null</code>
827
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
828
   * @see #insert(int, char[], int, int)
829
   */
830
  public StringBuffer insert(int offset, char[] data)
831
  {
832
    return insert(offset, data, 0, data.length);
833
  }
834
 
835
  /**
836
   * Insert the <code>String</code> value of the argument into this
837
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
838
   * to <code>String</code>.
839
   *
840
   * @param offset the place to insert in this buffer
841
   * @param bool the <code>boolean</code> to convert and insert
842
   * @return this <code>StringBuffer</code>
843
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
844
   * @see String#valueOf(boolean)
845
   */
846
  public StringBuffer insert(int offset, boolean bool)
847
  {
848
    return insert(offset, bool ? "true" : "false");
849
  }
850
 
851
  /**
852
   * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
853
   *
854
   * @param offset the place to insert in this buffer
855
   * @param ch the <code>char</code> to insert
856
   * @return this <code>StringBuffer</code>
857
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
858
   */
859
  public synchronized StringBuffer insert(int offset, char ch)
860
  {
861
    if (offset < 0 || offset > count)
862
      throw new StringIndexOutOfBoundsException(offset);
863
    ensureCapacity_unsynchronized(count + 1);
864
    VMSystem.arraycopy(value, offset, value, offset + 1, count - offset);
865
    value[offset] = ch;
866
    count++;
867
    return this;
868
  }
869
 
870
  /**
871
   * Insert the <code>String</code> value of the argument into this
872
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
873
   * to <code>String</code>.
874
   *
875
   * @param offset the place to insert in this buffer
876
   * @param inum the <code>int</code> to convert and insert
877
   * @return this <code>StringBuffer</code>
878
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
879
   * @see String#valueOf(int)
880
   */
881
  public StringBuffer insert(int offset, int inum)
882
  {
883
    return insert(offset, String.valueOf(inum));
884
  }
885
 
886
  /**
887
   * Insert the <code>String</code> value of the argument into this
888
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
889
   * to <code>String</code>.
890
   *
891
   * @param offset the place to insert in this buffer
892
   * @param lnum the <code>long</code> to convert and insert
893
   * @return this <code>StringBuffer</code>
894
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
895
   * @see String#valueOf(long)
896
   */
897
  public StringBuffer insert(int offset, long lnum)
898
  {
899
    return insert(offset, Long.toString(lnum, 10));
900
  }
901
 
902
  /**
903
   * Insert the <code>String</code> value of the argument into this
904
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
905
   * to <code>String</code>.
906
   *
907
   * @param offset the place to insert in this buffer
908
   * @param fnum the <code>float</code> to convert and insert
909
   * @return this <code>StringBuffer</code>
910
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
911
   * @see String#valueOf(float)
912
   */
913
  public StringBuffer insert(int offset, float fnum)
914
  {
915
    return insert(offset, Float.toString(fnum));
916
  }
917
 
918
  /**
919
   * Insert the <code>String</code> value of the argument into this
920
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
921
   * to <code>String</code>.
922
   *
923
   * @param offset the place to insert in this buffer
924
   * @param dnum the <code>double</code> to convert and insert
925
   * @return this <code>StringBuffer</code>
926
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
927
   * @see String#valueOf(double)
928
   */
929
  public StringBuffer insert(int offset, double dnum)
930
  {
931
    return insert(offset, Double.toString(dnum));
932
  }
933
 
934
  /**
935
   * Finds the first instance of a substring in this StringBuffer.
936
   *
937
   * @param str String to find
938
   * @return location (base 0) of the String, or -1 if not found
939
   * @throws NullPointerException if str is null
940
   * @see #indexOf(String, int)
941
   * @since 1.4
942
   */
943
  public int indexOf(String str)
944
  {
945
    return indexOf(str, 0);
946
  }
947
 
948
  /**
949
   * Finds the first instance of a String in this StringBuffer, starting at
950
   * a given index.  If starting index is less than 0, the search starts at
951
   * the beginning of this String.  If the starting index is greater than the
952
   * length of this String, or the substring is not found, -1 is returned.
953
   *
954
   * @param str String to find
955
   * @param fromIndex index to start the search
956
   * @return location (base 0) of the String, or -1 if not found
957
   * @throws NullPointerException if str is null
958
   * @since 1.4
959
   */
960
  public synchronized int indexOf(String str, int fromIndex)
961
  {
962
    if (fromIndex < 0)
963
      fromIndex = 0;
964
    int limit = count - str.count;
965
    for ( ; fromIndex <= limit; fromIndex++)
966
      if (regionMatches(fromIndex, str))
967
        return fromIndex;
968
    return -1;
969
  }
970
 
971
  /**
972
   * Finds the last instance of a substring in this StringBuffer.
973
   *
974
   * @param str String to find
975
   * @return location (base 0) of the String, or -1 if not found
976
   * @throws NullPointerException if str is null
977
   * @see #lastIndexOf(String, int)
978
   * @since 1.4
979
   */
980
  public int lastIndexOf(String str)
981
  {
982
    return lastIndexOf(str, count - str.count);
983
  }
984
 
985
  /**
986
   * Finds the last instance of a String in this StringBuffer, starting at a
987
   * given index.  If starting index is greater than the maximum valid index,
988
   * then the search begins at the end of this String.  If the starting index
989
   * is less than zero, or the substring is not found, -1 is returned.
990
   *
991
   * @param str String to find
992
   * @param fromIndex index to start the search
993
   * @return location (base 0) of the String, or -1 if not found
994
   * @throws NullPointerException if str is null
995
   * @since 1.4
996
   */
997
  public synchronized int lastIndexOf(String str, int fromIndex)
998
  {
999
    fromIndex = Math.min(fromIndex, count - str.count);
1000
    for ( ; fromIndex >= 0; fromIndex--)
1001
      if (regionMatches(fromIndex, str))
1002
        return fromIndex;
1003
    return -1;
1004
  }
1005
 
1006
  /**
1007
   * Reverse the characters in this StringBuffer. The same sequence of
1008
   * characters exists, but in the reverse index ordering.
1009
   *
1010
   * @return this <code>StringBuffer</code>
1011
   */
1012
  public synchronized StringBuffer reverse()
1013
  {
1014
    // Call ensureCapacity to enforce copy-on-write.
1015
    ensureCapacity_unsynchronized(count);
1016
    for (int i = count >> 1, j = count - i; --i >= 0; ++j)
1017
      {
1018
        char c = value[i];
1019
        value[i] = value[j];
1020
        value[j] = c;
1021
      }
1022
    return this;
1023
  }
1024
 
1025
  /**
1026
   * Convert this <code>StringBuffer</code> to a <code>String</code>. The
1027
   * String is composed of the characters currently in this StringBuffer. Note
1028
   * that the result is a copy, and that future modifications to this buffer
1029
   * do not affect the String.
1030
   *
1031
   * @return the characters in this StringBuffer
1032
   */
1033
  public String toString()
1034
  {
1035
    // The string will set this.shared = true.
1036
    return new String(this);
1037
  }
1038
 
1039
  /**
1040
   * This may reduce the amount of memory used by the StringBuffer,
1041
   * by resizing the internal array to remove unused space.  However,
1042
   * this method is not required to resize, so this behavior cannot
1043
   * be relied upon.
1044
   * @since 1.5
1045
   */
1046
  public synchronized void trimToSize()
1047
  {
1048
    int wouldSave = value.length - count;
1049
    // Some random heuristics: if we save less than 20 characters, who
1050
    // cares.
1051
    if (wouldSave < 20)
1052
      return;
1053
    // If we save more than 200 characters, shrink.
1054
    // If we save more than 1/4 of the buffer, shrink.
1055
    if (wouldSave > 200 || wouldSave * 4 > value.length)
1056
      {
1057
        char[] newValue = new char[count];
1058
        VMSystem.arraycopy(value, 0, newValue, 0, count);
1059
        value = newValue;
1060
      }
1061
  }
1062
 
1063
  /**
1064
   * Return the number of code points between two indices in the
1065
   * <code>StringBuffer</code>.  An unpaired surrogate counts as a
1066
   * code point for this purpose.  Characters outside the indicated
1067
   * range are not examined, even if the range ends in the middle of a
1068
   * surrogate pair.
1069
   *
1070
   * @param start the starting index
1071
   * @param end one past the ending index
1072
   * @return the number of code points
1073
   * @since 1.5
1074
   */
1075
  public synchronized int codePointCount(int start, int end)
1076
  {
1077
    if (start < 0 || end >= count || start > end)
1078
      throw new StringIndexOutOfBoundsException();
1079
 
1080
    int count = 0;
1081
    while (start < end)
1082
      {
1083
        char base = value[start];
1084
        if (base < Character.MIN_HIGH_SURROGATE
1085
            || base > Character.MAX_HIGH_SURROGATE
1086
            || start == end
1087
            || start == count
1088
            || value[start + 1] < Character.MIN_LOW_SURROGATE
1089
            || value[start + 1] > Character.MAX_LOW_SURROGATE)
1090
          {
1091
            // Nothing.
1092
          }
1093
        else
1094
          {
1095
            // Surrogate pair.
1096
            ++start;
1097
          }
1098
        ++start;
1099
        ++count;
1100
      }
1101
    return count;
1102
  }
1103
 
1104
  /**
1105
   * Starting at the given index, this counts forward by the indicated
1106
   * number of code points, and then returns the resulting index.  An
1107
   * unpaired surrogate counts as a single code point for this
1108
   * purpose.
1109
   *
1110
   * @param start the starting index
1111
   * @param codePoints the number of code points
1112
   * @return the resulting index
1113
   * @since 1.5
1114
   */
1115
  public synchronized int offsetByCodePoints(int start, int codePoints)
1116
  {
1117
    while (codePoints > 0)
1118
      {
1119
        char base = value[start];
1120
        if (base < Character.MIN_HIGH_SURROGATE
1121
            || base > Character.MAX_HIGH_SURROGATE
1122
            || start == count
1123
            || value[start + 1] < Character.MIN_LOW_SURROGATE
1124
            || value[start + 1] > Character.MAX_LOW_SURROGATE)
1125
          {
1126
            // Nothing.
1127
          }
1128
        else
1129
          {
1130
            // Surrogate pair.
1131
            ++start;
1132
          }
1133
        ++start;
1134
        --codePoints;
1135
      }
1136
    return start;
1137
  }
1138
 
1139
  /**
1140
   * An unsynchronized version of ensureCapacity, used internally to avoid
1141
   * the cost of a second lock on the same object. This also has the side
1142
   * effect of duplicating the array, if it was shared (to form copy-on-write
1143
   * semantics).
1144
   *
1145
   * @param minimumCapacity the minimum capacity
1146
   * @see #ensureCapacity(int)
1147
   */
1148
  private void ensureCapacity_unsynchronized(int minimumCapacity)
1149
  {
1150
    if (shared || minimumCapacity > value.length)
1151
      {
1152
        // We don't want to make a larger vector when `shared' is
1153
        // set.  If we do, then setLength becomes very inefficient
1154
        // when repeatedly reusing a StringBuffer in a loop.
1155
        int max = (minimumCapacity > value.length
1156
                   ? value.length * 2 + 2
1157
                   : value.length);
1158
        minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
1159
        char[] nb = new char[minimumCapacity];
1160
        VMSystem.arraycopy(value, 0, nb, 0, count);
1161
        value = nb;
1162
        shared = false;
1163
      }
1164
  }
1165
 
1166
  /**
1167
   * Predicate which determines if a substring of this matches another String
1168
   * starting at a specified offset for each String and continuing for a
1169
   * specified length. This is more efficient than creating a String to call
1170
   * indexOf on.
1171
   *
1172
   * @param toffset index to start comparison at for this String
1173
   * @param other non-null String to compare to region of this
1174
   * @return true if regions match, false otherwise
1175
   * @see #indexOf(String, int)
1176
   * @see #lastIndexOf(String, int)
1177
   * @see String#regionMatches(boolean, int, String, int, int)
1178
   */
1179
  private boolean regionMatches(int toffset, String other)
1180
  {
1181
    int len = other.count;
1182
    int index = other.offset;
1183
    while (--len >= 0)
1184
      if (value[toffset++] != other.value[index++])
1185
        return false;
1186
    return true;
1187
  }
1188
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.