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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [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, 2006
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
    System.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
        System.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
    System.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
  // GCJ LOCAL: this is native for efficiency.
528
  public native StringBuffer append (int inum);
529
 
530
  /**
531
   * Append the <code>String</code> value of the argument to this
532
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
533
   * to <code>String</code>.
534
   *
535
   * @param lnum the <code>long</code> to convert and append
536
   * @return this <code>StringBuffer</code>
537
   * @see String#valueOf(long)
538
   */
539
  public StringBuffer append(long lnum)
540
  {
541
    return append(Long.toString(lnum, 10));
542
  }
543
 
544
  /**
545
   * Append the <code>String</code> value of the argument to this
546
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
547
   * to <code>String</code>.
548
   *
549
   * @param fnum the <code>float</code> to convert and append
550
   * @return this <code>StringBuffer</code>
551
   * @see String#valueOf(float)
552
   */
553
  public StringBuffer append(float fnum)
554
  {
555
    return append(Float.toString(fnum));
556
  }
557
 
558
  /**
559
   * Append the <code>String</code> value of the argument to this
560
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
561
   * to <code>String</code>.
562
   *
563
   * @param dnum the <code>double</code> to convert and append
564
   * @return this <code>StringBuffer</code>
565
   * @see String#valueOf(double)
566
   */
567
  public StringBuffer append(double dnum)
568
  {
569
    return append(Double.toString(dnum));
570
  }
571
 
572
  /**
573
   * Delete characters from this <code>StringBuffer</code>.
574
   * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
575
   * harmless for end to be larger than length().
576
   *
577
   * @param start the first character to delete
578
   * @param end the index after the last character to delete
579
   * @return this <code>StringBuffer</code>
580
   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
581
   * @since 1.2
582
   */
583
  public synchronized StringBuffer delete(int start, int end)
584
  {
585
    if (start < 0 || start > count || start > end)
586
      throw new StringIndexOutOfBoundsException(start);
587
    if (end > count)
588
      end = count;
589
    // This will unshare if required.
590
    ensureCapacity_unsynchronized(count);
591
    if (count - end != 0)
592
      System.arraycopy(value, end, value, start, count - end);
593
    count -= end - start;
594
    return this;
595
  }
596
 
597
  /**
598
   * Delete a character from this <code>StringBuffer</code>.
599
   *
600
   * @param index the index of the character to delete
601
   * @return this <code>StringBuffer</code>
602
   * @throws StringIndexOutOfBoundsException if index is out of bounds
603
   * @since 1.2
604
   */
605
  public StringBuffer deleteCharAt(int index)
606
  {
607
    return delete(index, index + 1);
608
  }
609
 
610
  /**
611
   * Replace characters between index <code>start</code> (inclusive) and
612
   * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
613
   * is larger than the size of this StringBuffer, all characters after
614
   * <code>start</code> are replaced.
615
   *
616
   * @param start the beginning index of characters to delete (inclusive)
617
   * @param end the ending index of characters to delete (exclusive)
618
   * @param str the new <code>String</code> to insert
619
   * @return this <code>StringBuffer</code>
620
   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
621
   * @throws NullPointerException if str is null
622
   * @since 1.2
623
   */
624
  public synchronized StringBuffer replace(int start, int end, String str)
625
  {
626
    if (start < 0 || start > count || start > end)
627
      throw new StringIndexOutOfBoundsException(start);
628
 
629
    int len = str.count;
630
    // Calculate the difference in 'count' after the replace.
631
    int delta = len - (end > count ? count : end) + start;
632
    ensureCapacity_unsynchronized(count + delta);
633
 
634
    if (delta != 0 && end < count)
635
      System.arraycopy(value, end, value, end + delta, count - end);
636
 
637
    str.getChars(0, len, value, start);
638
    count += delta;
639
    return this;
640
  }
641
 
642
  /**
643
   * Creates a substring of this StringBuffer, starting at a specified index
644
   * and ending at the end of this StringBuffer.
645
   *
646
   * @param beginIndex index to start substring (base 0)
647
   * @return new String which is a substring of this StringBuffer
648
   * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
649
   * @see #substring(int, int)
650
   * @since 1.2
651
   */
652
  public String substring(int beginIndex)
653
  {
654
    return substring(beginIndex, count);
655
  }
656
 
657
  /**
658
   * Creates a substring of this StringBuffer, starting at a specified index
659
   * and ending at one character before a specified index. This is implemented
660
   * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
661
   * the CharSequence interface.
662
   *
663
   * @param beginIndex index to start at (inclusive, base 0)
664
   * @param endIndex index to end at (exclusive)
665
   * @return new String which is a substring of this StringBuffer
666
   * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
667
   *         bounds
668
   * @see #substring(int, int)
669
   * @since 1.4
670
   */
671
  public CharSequence subSequence(int beginIndex, int endIndex)
672
  {
673
    return substring(beginIndex, endIndex);
674
  }
675
 
676
  /**
677
   * Creates a substring of this StringBuffer, starting at a specified index
678
   * and ending at one character before a specified index.
679
   *
680
   * @param beginIndex index to start at (inclusive, base 0)
681
   * @param endIndex index to end at (exclusive)
682
   * @return new String which is a substring of this StringBuffer
683
   * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
684
   *         of bounds
685
   * @since 1.2
686
   */
687
  public synchronized String substring(int beginIndex, int endIndex)
688
  {
689
    int len = endIndex - beginIndex;
690
    if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
691
      throw new StringIndexOutOfBoundsException();
692
    if (len == 0)
693
      return "";
694
    // Don't copy unless substring is smaller than 1/4 of the buffer.
695
    boolean share_buffer = ((len << 2) >= value.length);
696
    if (share_buffer)
697
      this.shared = true;
698
    // Package constructor avoids an array copy.
699
    return new String(value, beginIndex, len, share_buffer);
700
  }
701
 
702
  /**
703
   * Insert a subarray of the <code>char[]</code> argument into this
704
   * <code>StringBuffer</code>.
705
   *
706
   * @param offset the place to insert in this buffer
707
   * @param str the <code>char[]</code> to insert
708
   * @param str_offset the index in <code>str</code> to start inserting from
709
   * @param len the number of characters to insert
710
   * @return this <code>StringBuffer</code>
711
   * @throws NullPointerException if <code>str</code> is <code>null</code>
712
   * @throws StringIndexOutOfBoundsException if any index is out of bounds
713
   * @since 1.2
714
   */
715
  public synchronized StringBuffer insert(int offset,
716
                                          char[] str, int str_offset, int len)
717
  {
718
    if (offset < 0 || offset > count || len < 0
719
        || str_offset < 0 || str_offset > str.length - len)
720
      throw new StringIndexOutOfBoundsException();
721
    ensureCapacity_unsynchronized(count + len);
722
    System.arraycopy(value, offset, value, offset + len, count - offset);
723
    System.arraycopy(str, str_offset, value, offset, len);
724
    count += len;
725
    return this;
726
  }
727
 
728
  /**
729
   * Insert the <code>String</code> value of the argument into this
730
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
731
   * to <code>String</code>.
732
   *
733
   * @param offset the place to insert in this buffer
734
   * @param obj the <code>Object</code> to convert and insert
735
   * @return this <code>StringBuffer</code>
736
   * @exception StringIndexOutOfBoundsException if offset is out of bounds
737
   * @see String#valueOf(Object)
738
   */
739
  public StringBuffer insert(int offset, Object obj)
740
  {
741
    return insert(offset, obj == null ? "null" : obj.toString());
742
  }
743
 
744
  /**
745
   * Insert the <code>String</code> argument into this
746
   * <code>StringBuffer</code>. If str is null, the String "null" is used
747
   * instead.
748
   *
749
   * @param offset the place to insert in this buffer
750
   * @param str the <code>String</code> to insert
751
   * @return this <code>StringBuffer</code>
752
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
753
   */
754
  public synchronized StringBuffer insert(int offset, String str)
755
  {
756
    if (offset < 0 || offset > count)
757
      throw new StringIndexOutOfBoundsException(offset);
758
    if (str == null)
759
      str = "null";
760
    int len = str.count;
761
    ensureCapacity_unsynchronized(count + len);
762
    System.arraycopy(value, offset, value, offset + len, count - offset);
763
    str.getChars(0, len, value, offset);
764
    count += len;
765
    return this;
766
  }
767
 
768
  /**
769
   * Insert the <code>CharSequence</code> argument into this
770
   * <code>StringBuffer</code>.  If the sequence is null, the String
771
   * "null" is used instead.
772
   *
773
   * @param offset the place to insert in this buffer
774
   * @param sequence the <code>CharSequence</code> to insert
775
   * @return this <code>StringBuffer</code>
776
   * @throws IndexOutOfBoundsException if offset is out of bounds
777
   * @since 1.5
778
   */
779
  public synchronized StringBuffer insert(int offset, CharSequence sequence)
780
  {
781
    if (sequence == null)
782
      sequence = "null";
783
    return insert(offset, sequence, 0, sequence.length());
784
  }
785
 
786
  /**
787
   * Insert a subsequence of the <code>CharSequence</code> argument into this
788
   * <code>StringBuffer</code>.  If the sequence is null, the String
789
   * "null" is used instead.
790
   *
791
   * @param offset the place to insert in this buffer
792
   * @param sequence the <code>CharSequence</code> to insert
793
   * @param start the starting index of the subsequence
794
   * @param end one past the ending index of the subsequence
795
   * @return this <code>StringBuffer</code>
796
   * @throws IndexOutOfBoundsException if offset, start,
797
   * or end are out of bounds
798
   * @since 1.5
799
   */
800
  public synchronized StringBuffer insert(int offset, CharSequence sequence,
801
                                          int start, int end)
802
  {
803
    if (sequence == null)
804
      sequence = "null";
805
    if (start < 0 || end < 0 || start > end || end > sequence.length())
806
      throw new IndexOutOfBoundsException();
807
    int len = end - start;
808
    ensureCapacity_unsynchronized(count + len);
809
    System.arraycopy(value, offset, value, offset + len, count - offset);
810
    for (int i = start; i < end; ++i)
811
      value[offset++] = sequence.charAt(i);
812
    count += len;
813
    return this;
814
  }
815
 
816
  /**
817
   * Insert the <code>char[]</code> argument into this
818
   * <code>StringBuffer</code>.
819
   *
820
   * @param offset the place to insert in this buffer
821
   * @param data the <code>char[]</code> to insert
822
   * @return this <code>StringBuffer</code>
823
   * @throws NullPointerException if <code>data</code> is <code>null</code>
824
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
825
   * @see #insert(int, char[], int, int)
826
   */
827
  public StringBuffer insert(int offset, char[] data)
828
  {
829
    return insert(offset, data, 0, data.length);
830
  }
831
 
832
  /**
833
   * Insert the <code>String</code> value of the argument into this
834
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
835
   * to <code>String</code>.
836
   *
837
   * @param offset the place to insert in this buffer
838
   * @param bool the <code>boolean</code> to convert and insert
839
   * @return this <code>StringBuffer</code>
840
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
841
   * @see String#valueOf(boolean)
842
   */
843
  public StringBuffer insert(int offset, boolean bool)
844
  {
845
    return insert(offset, bool ? "true" : "false");
846
  }
847
 
848
  /**
849
   * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
850
   *
851
   * @param offset the place to insert in this buffer
852
   * @param ch the <code>char</code> to insert
853
   * @return this <code>StringBuffer</code>
854
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
855
   */
856
  public synchronized StringBuffer insert(int offset, char ch)
857
  {
858
    if (offset < 0 || offset > count)
859
      throw new StringIndexOutOfBoundsException(offset);
860
    ensureCapacity_unsynchronized(count + 1);
861
    System.arraycopy(value, offset, value, offset + 1, count - offset);
862
    value[offset] = ch;
863
    count++;
864
    return this;
865
  }
866
 
867
  /**
868
   * Insert the <code>String</code> value of the argument into this
869
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
870
   * to <code>String</code>.
871
   *
872
   * @param offset the place to insert in this buffer
873
   * @param inum the <code>int</code> to convert and insert
874
   * @return this <code>StringBuffer</code>
875
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
876
   * @see String#valueOf(int)
877
   */
878
  public StringBuffer insert(int offset, int inum)
879
  {
880
    return insert(offset, String.valueOf(inum));
881
  }
882
 
883
  /**
884
   * Insert the <code>String</code> value of the argument into this
885
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
886
   * to <code>String</code>.
887
   *
888
   * @param offset the place to insert in this buffer
889
   * @param lnum the <code>long</code> to convert and insert
890
   * @return this <code>StringBuffer</code>
891
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
892
   * @see String#valueOf(long)
893
   */
894
  public StringBuffer insert(int offset, long lnum)
895
  {
896
    return insert(offset, Long.toString(lnum, 10));
897
  }
898
 
899
  /**
900
   * Insert the <code>String</code> value of the argument into this
901
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
902
   * to <code>String</code>.
903
   *
904
   * @param offset the place to insert in this buffer
905
   * @param fnum the <code>float</code> to convert and insert
906
   * @return this <code>StringBuffer</code>
907
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
908
   * @see String#valueOf(float)
909
   */
910
  public StringBuffer insert(int offset, float fnum)
911
  {
912
    return insert(offset, Float.toString(fnum));
913
  }
914
 
915
  /**
916
   * Insert the <code>String</code> value of the argument into this
917
   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
918
   * to <code>String</code>.
919
   *
920
   * @param offset the place to insert in this buffer
921
   * @param dnum the <code>double</code> to convert and insert
922
   * @return this <code>StringBuffer</code>
923
   * @throws StringIndexOutOfBoundsException if offset is out of bounds
924
   * @see String#valueOf(double)
925
   */
926
  public StringBuffer insert(int offset, double dnum)
927
  {
928
    return insert(offset, Double.toString(dnum));
929
  }
930
 
931
  /**
932
   * Finds the first instance of a substring in this StringBuffer.
933
   *
934
   * @param str String to find
935
   * @return location (base 0) of the String, or -1 if not found
936
   * @throws NullPointerException if str is null
937
   * @see #indexOf(String, int)
938
   * @since 1.4
939
   */
940
  public int indexOf(String str)
941
  {
942
    return indexOf(str, 0);
943
  }
944
 
945
  /**
946
   * Finds the first instance of a String in this StringBuffer, starting at
947
   * a given index.  If starting index is less than 0, the search starts at
948
   * the beginning of this String.  If the starting index is greater than the
949
   * length of this String, or the substring is not found, -1 is returned.
950
   *
951
   * @param str String to find
952
   * @param fromIndex index to start the search
953
   * @return location (base 0) of the String, or -1 if not found
954
   * @throws NullPointerException if str is null
955
   * @since 1.4
956
   */
957
  public synchronized int indexOf(String str, int fromIndex)
958
  {
959
    if (fromIndex < 0)
960
      fromIndex = 0;
961
    int limit = count - str.count;
962
    for ( ; fromIndex <= limit; fromIndex++)
963
      if (regionMatches(fromIndex, str))
964
        return fromIndex;
965
    return -1;
966
  }
967
 
968
  /**
969
   * Finds the last instance of a substring in this StringBuffer.
970
   *
971
   * @param str String to find
972
   * @return location (base 0) of the String, or -1 if not found
973
   * @throws NullPointerException if str is null
974
   * @see #lastIndexOf(String, int)
975
   * @since 1.4
976
   */
977
  public int lastIndexOf(String str)
978
  {
979
    return lastIndexOf(str, count - str.count);
980
  }
981
 
982
  /**
983
   * Finds the last instance of a String in this StringBuffer, starting at a
984
   * given index.  If starting index is greater than the maximum valid index,
985
   * then the search begins at the end of this String.  If the starting index
986
   * is less than zero, or the substring is not found, -1 is returned.
987
   *
988
   * @param str String to find
989
   * @param fromIndex index to start the search
990
   * @return location (base 0) of the String, or -1 if not found
991
   * @throws NullPointerException if str is null
992
   * @since 1.4
993
   */
994
  public synchronized int lastIndexOf(String str, int fromIndex)
995
  {
996
    fromIndex = Math.min(fromIndex, count - str.count);
997
    for ( ; fromIndex >= 0; fromIndex--)
998
      if (regionMatches(fromIndex, str))
999
        return fromIndex;
1000
    return -1;
1001
  }
1002
 
1003
  /**
1004
   * Reverse the characters in this StringBuffer. The same sequence of
1005
   * characters exists, but in the reverse index ordering.
1006
   *
1007
   * @return this <code>StringBuffer</code>
1008
   */
1009
  public synchronized StringBuffer reverse()
1010
  {
1011
    // Call ensureCapacity to enforce copy-on-write.
1012
    ensureCapacity_unsynchronized(count);
1013
    for (int i = count >> 1, j = count - i; --i >= 0; ++j)
1014
      {
1015
        char c = value[i];
1016
        value[i] = value[j];
1017
        value[j] = c;
1018
      }
1019
    return this;
1020
  }
1021
 
1022
  /**
1023
   * Convert this <code>StringBuffer</code> to a <code>String</code>. The
1024
   * String is composed of the characters currently in this StringBuffer. Note
1025
   * that the result is a copy, and that future modifications to this buffer
1026
   * do not affect the String.
1027
   *
1028
   * @return the characters in this StringBuffer
1029
   */
1030
  public String toString()
1031
  {
1032
    // The string will set this.shared = true.
1033
    return new String(this);
1034
  }
1035
 
1036
  /**
1037
   * This may reduce the amount of memory used by the StringBuffer,
1038
   * by resizing the internal array to remove unused space.  However,
1039
   * this method is not required to resize, so this behavior cannot
1040
   * be relied upon.
1041
   * @since 1.5
1042
   */
1043
  public synchronized void trimToSize()
1044
  {
1045
    int wouldSave = value.length - count;
1046
    // Some random heuristics: if we save less than 20 characters, who
1047
    // cares.
1048
    if (wouldSave < 20)
1049
      return;
1050
    // If we save more than 200 characters, shrink.
1051
    // If we save more than 1/4 of the buffer, shrink.
1052
    if (wouldSave > 200 || wouldSave * 4 > value.length)
1053
      {
1054
        char[] newValue = new char[count];
1055
        System.arraycopy(value, 0, newValue, 0, count);
1056
        value = newValue;
1057
      }
1058
  }
1059
 
1060
  /**
1061
   * Return the number of code points between two indices in the
1062
   * <code>StringBuffer</code>.  An unpaired surrogate counts as a
1063
   * code point for this purpose.  Characters outside the indicated
1064
   * range are not examined, even if the range ends in the middle of a
1065
   * surrogate pair.
1066
   *
1067
   * @param start the starting index
1068
   * @param end one past the ending index
1069
   * @return the number of code points
1070
   * @since 1.5
1071
   */
1072
  public synchronized int codePointCount(int start, int end)
1073
  {
1074
    if (start < 0 || end >= count || start > end)
1075
      throw new StringIndexOutOfBoundsException();
1076
 
1077
    int count = 0;
1078
    while (start < end)
1079
      {
1080
        char base = value[start];
1081
        if (base < Character.MIN_HIGH_SURROGATE
1082
            || base > Character.MAX_HIGH_SURROGATE
1083
            || start == end
1084
            || start == count
1085
            || value[start + 1] < Character.MIN_LOW_SURROGATE
1086
            || value[start + 1] > Character.MAX_LOW_SURROGATE)
1087
          {
1088
            // Nothing.
1089
          }
1090
        else
1091
          {
1092
            // Surrogate pair.
1093
            ++start;
1094
          }
1095
        ++start;
1096
        ++count;
1097
      }
1098
    return count;
1099
  }
1100
 
1101
  /**
1102
   * Starting at the given index, this counts forward by the indicated
1103
   * number of code points, and then returns the resulting index.  An
1104
   * unpaired surrogate counts as a single code point for this
1105
   * purpose.
1106
   *
1107
   * @param start the starting index
1108
   * @param codePoints the number of code points
1109
   * @return the resulting index
1110
   * @since 1.5
1111
   */
1112
  public synchronized int offsetByCodePoints(int start, int codePoints)
1113
  {
1114
    while (codePoints > 0)
1115
      {
1116
        char base = value[start];
1117
        if (base < Character.MIN_HIGH_SURROGATE
1118
            || base > Character.MAX_HIGH_SURROGATE
1119
            || start == count
1120
            || value[start + 1] < Character.MIN_LOW_SURROGATE
1121
            || value[start + 1] > Character.MAX_LOW_SURROGATE)
1122
          {
1123
            // Nothing.
1124
          }
1125
        else
1126
          {
1127
            // Surrogate pair.
1128
            ++start;
1129
          }
1130
        ++start;
1131
        --codePoints;
1132
      }
1133
    return start;
1134
  }
1135
 
1136
  /**
1137
   * An unsynchronized version of ensureCapacity, used internally to avoid
1138
   * the cost of a second lock on the same object. This also has the side
1139
   * effect of duplicating the array, if it was shared (to form copy-on-write
1140
   * semantics).
1141
   *
1142
   * @param minimumCapacity the minimum capacity
1143
   * @see #ensureCapacity(int)
1144
   */
1145
  private void ensureCapacity_unsynchronized(int minimumCapacity)
1146
  {
1147
    if (shared || minimumCapacity > value.length)
1148
      {
1149
        // We don't want to make a larger vector when `shared' is
1150
        // set.  If we do, then setLength becomes very inefficient
1151
        // when repeatedly reusing a StringBuffer in a loop.
1152
        int max = (minimumCapacity > value.length
1153
                   ? value.length * 2 + 2
1154
                   : value.length);
1155
        minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
1156
        char[] nb = new char[minimumCapacity];
1157
        System.arraycopy(value, 0, nb, 0, count);
1158
        value = nb;
1159
        shared = false;
1160
      }
1161
  }
1162
 
1163
  /**
1164
   * Predicate which determines if a substring of this matches another String
1165
   * starting at a specified offset for each String and continuing for a
1166
   * specified length. This is more efficient than creating a String to call
1167
   * indexOf on.
1168
   *
1169
   * @param toffset index to start comparison at for this String
1170
   * @param other non-null String to compare to region of this
1171
   * @return true if regions match, false otherwise
1172
   * @see #indexOf(String, int)
1173
   * @see #lastIndexOf(String, int)
1174
   * @see String#regionMatches(boolean, int, String, int, int)
1175
   */
1176
  // GCJ LOCAL: native for gcj.
1177
  private native boolean regionMatches(int toffset, String other);
1178
}

powered by: WebSVN 2.1.0

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