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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [lang/] [String.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* String.java -- immutable character sequences; the object of string literals
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
 
40
package java.lang;
41
 
42
import gnu.java.lang.CharData;
43
import gnu.java.lang.CPStringBuilder;
44
 
45
import java.io.Serializable;
46
import java.io.UnsupportedEncodingException;
47
import java.nio.ByteBuffer;
48
import java.nio.CharBuffer;
49
import java.nio.charset.CharacterCodingException;
50
import java.nio.charset.Charset;
51
import java.nio.charset.CharsetDecoder;
52
import java.nio.charset.CharsetEncoder;
53
import java.nio.charset.CodingErrorAction;
54
import java.nio.charset.IllegalCharsetNameException;
55
import java.nio.charset.UnsupportedCharsetException;
56
import java.text.Collator;
57
import java.util.Comparator;
58
import java.util.Formatter;
59
import java.util.Locale;
60
import java.util.regex.Matcher;
61
import java.util.regex.Pattern;
62
import java.util.regex.PatternSyntaxException;
63
 
64
/**
65
 * Strings represent an immutable set of characters.  All String literals
66
 * are instances of this class, and two string literals with the same contents
67
 * refer to the same String object.
68
 *
69
 * <p>This class also includes a number of methods for manipulating the
70
 * contents of strings (of course, creating a new object if there are any
71
 * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
72
 * standards, where some character sequences have a different number of
73
 * characters in the uppercase version than the lower case.
74
 *
75
 * <p>Strings are special, in that they are the only object with an overloaded
76
 * operator. When you use '+' with at least one String argument, both
77
 * arguments have String conversion performed on them, and another String (not
78
 * guaranteed to be unique) results.
79
 *
80
 * <p>String is special-cased when doing data serialization - rather than
81
 * listing the fields of this class, a String object is converted to a string
82
 * literal in the object stream.
83
 *
84
 * @author Paul N. Fisher
85
 * @author Eric Blake (ebb9@email.byu.edu)
86
 * @author Per Bothner (bothner@cygnus.com)
87
 * @author Tom Tromey (tromey@redhat.com)
88
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
89
 * @since 1.0
90
 * @status updated to 1.4; but could use better data sharing via offset field
91
 */
92
public final class String
93
  implements Serializable, Comparable<String>, CharSequence
94
{
95
  // WARNING: String is a CORE class in the bootstrap cycle. See the comments
96
  // in vm/reference/java/lang/Runtime for implications of this fact.
97
 
98
  /**
99
   * This is probably not necessary because this class is special cased already
100
   * but it will avoid showing up as a discrepancy when comparing SUIDs.
101
   */
102
  private static final long serialVersionUID = -6849794470754667710L;
103
 
104
  /**
105
   * Stores unicode multi-character uppercase expansion table.
106
   * @see #toUpperCase(Locale)
107
   * @see CharData#UPPER_EXPAND
108
   */
109
  private static final char[] upperExpand
110
        = zeroBasedStringValue(CharData.UPPER_EXPAND);
111
 
112
  /**
113
   * Stores unicode multi-character uppercase special casing table.
114
   * @see #upperCaseExpansion(char)
115
   * @see CharData#UPPER_SPECIAL
116
   */
117
  private static final char[] upperSpecial
118
          = zeroBasedStringValue(CharData.UPPER_SPECIAL);
119
 
120
  /**
121
   * Characters which make up the String.
122
   * Package access is granted for use by StringBuffer.
123
   */
124
  final char[] value;
125
 
126
  /**
127
   * Holds the number of characters in value.  This number is generally
128
   * the same as value.length, but can be smaller because substrings and
129
   * StringBuffers can share arrays. Package visible for use by trusted code.
130
   */
131
  final int count;
132
 
133
  /**
134
   * Caches the result of hashCode().  If this value is zero, the hashcode
135
   * is considered uncached (even if 0 is the correct hash value).
136
   */
137
  private int cachedHashCode;
138
 
139
  /**
140
   * Holds the starting position for characters in value[].  Since
141
   * substring()'s are common, the use of offset allows the operation
142
   * to perform in O(1). Package access is granted for use by StringBuffer.
143
   */
144
  final int offset;
145
 
146
  /**
147
   * An implementation for {@link #CASE_INSENSITIVE_ORDER}.
148
   * This must be {@link Serializable}. The class name is dictated by
149
   * compatibility with Sun's JDK.
150
   */
151
  private static final class CaseInsensitiveComparator
152
    implements Comparator<String>, Serializable
153
  {
154
    /**
155
     * Compatible with JDK 1.2.
156
     */
157
    private static final long serialVersionUID = 8575799808933029326L;
158
 
159
    /**
160
     * The default private constructor generates unnecessary overhead.
161
     */
162
    CaseInsensitiveComparator() {}
163
 
164
    /**
165
     * Compares to Strings, using
166
     * <code>String.compareToIgnoreCase(String)</code>.
167
     *
168
     * @param o1 the first string
169
     * @param o2 the second string
170
     * @return &lt; 0, 0, or &gt; 0 depending on the case-insensitive
171
     *         comparison of the two strings.
172
     * @throws NullPointerException if either argument is null
173
     * @throws ClassCastException if either argument is not a String
174
     * @see #compareToIgnoreCase(String)
175
     */
176
    public int compare(String o1, String o2)
177
    {
178
      return o1.compareToIgnoreCase(o2);
179
    }
180
  } // class CaseInsensitiveComparator
181
 
182
  /**
183
   * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
184
   * This comparator is {@link Serializable}. Note that it ignores Locale,
185
   * for that, you want a Collator.
186
   *
187
   * @see Collator#compare(String, String)
188
   * @since 1.2
189
   */
190
  public static final Comparator<String> CASE_INSENSITIVE_ORDER
191
    = new CaseInsensitiveComparator();
192
 
193
  /**
194
   * Creates an empty String (length 0). Unless you really need a new object,
195
   * consider using <code>""</code> instead.
196
   */
197
  public String()
198
  {
199
    value = "".value;
200
    offset = 0;
201
    count = 0;
202
  }
203
 
204
  /**
205
   * Copies the contents of a String to a new String. Since Strings are
206
   * immutable, only a shallow copy is performed.
207
   *
208
   * @param str String to copy
209
   * @throws NullPointerException if value is null
210
   */
211
  public String(String str)
212
  {
213
    value = str.value;
214
    offset = str.offset;
215
    count = str.count;
216
    cachedHashCode = str.cachedHashCode;
217
  }
218
 
219
  /**
220
   * Creates a new String using the character sequence of the char array.
221
   * Subsequent changes to data do not affect the String.
222
   *
223
   * @param data char array to copy
224
   * @throws NullPointerException if data is null
225
   */
226
  public String(char[] data)
227
  {
228
    this(data, 0, data.length, false);
229
  }
230
 
231
  /**
232
   * Creates a new String using the character sequence of a subarray of
233
   * characters. The string starts at offset, and copies count chars.
234
   * Subsequent changes to data do not affect the String.
235
   *
236
   * @param data char array to copy
237
   * @param offset position (base 0) to start copying out of data
238
   * @param count the number of characters from data to copy
239
   * @throws NullPointerException if data is null
240
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
241
   *         || offset + count &lt; 0 (overflow)
242
   *         || offset + count &gt; data.length)
243
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
244
   */
245
  public String(char[] data, int offset, int count)
246
  {
247
    this(data, offset, count, false);
248
  }
249
 
250
  /**
251
   * Creates a new String using an 8-bit array of integer values, starting at
252
   * an offset, and copying up to the count. Each character c, using
253
   * corresponding byte b, is created in the new String as if by performing:
254
   *
255
   * <pre>
256
   * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
257
   * </pre>
258
   *
259
   * @param ascii array of integer values
260
   * @param hibyte top byte of each Unicode character
261
   * @param offset position (base 0) to start copying out of ascii
262
   * @param count the number of characters from ascii to copy
263
   * @throws NullPointerException if ascii is null
264
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
265
   *         || offset + count &lt; 0 (overflow)
266
   *         || offset + count &gt; ascii.length)
267
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
268
   * @see #String(byte[])
269
   * @see #String(byte[], String)
270
   * @see #String(byte[], int, int)
271
   * @see #String(byte[], int, int, String)
272
   * @deprecated use {@link #String(byte[], int, int, String)} to perform
273
   *             correct encoding
274
   */
275
  public String(byte[] ascii, int hibyte, int offset, int count)
276
  {
277
    if (offset < 0)
278
      throw new StringIndexOutOfBoundsException("offset: " + offset);
279
    if (count < 0)
280
      throw new StringIndexOutOfBoundsException("count: " + count);
281
    // equivalent to: offset + count < 0 || offset + count > ascii.length
282
    if (ascii.length - offset < count)
283
      throw new StringIndexOutOfBoundsException("offset + count: "
284
                                                + (offset + count));
285
    value = new char[count];
286
    this.offset = 0;
287
    this.count = count;
288
    hibyte <<= 8;
289
    offset += count;
290
    while (--count >= 0)
291
      value[count] = (char) (hibyte | (ascii[--offset] & 0xff));
292
  }
293
 
294
  /**
295
   * Creates a new String using an 8-bit array of integer values. Each
296
   * character c, using corresponding byte b, is created in the new String
297
   * as if by performing:
298
   *
299
   * <pre>
300
   * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
301
   * </pre>
302
   *
303
   * @param ascii array of integer values
304
   * @param hibyte top byte of each Unicode character
305
   * @throws NullPointerException if ascii is null
306
   * @see #String(byte[])
307
   * @see #String(byte[], String)
308
   * @see #String(byte[], int, int)
309
   * @see #String(byte[], int, int, String)
310
   * @see #String(byte[], int, int, int)
311
   * @deprecated use {@link #String(byte[], String)} to perform
312
   *             correct encoding
313
   */
314
  public String(byte[] ascii, int hibyte)
315
  {
316
    this(ascii, hibyte, 0, ascii.length);
317
  }
318
 
319
  /**
320
   * Creates a new String using the portion of the byte array starting at the
321
   * offset and ending at offset + count. Uses the specified encoding type
322
   * to decode the byte array, so the resulting string may be longer or
323
   * shorter than the byte array. For more decoding control, use
324
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
325
   * see {@link java.nio.charset.Charset}. The behavior is not specified if
326
   * the decoder encounters invalid characters; this implementation throws
327
   * an Error.
328
   *
329
   * @param data byte array to copy
330
   * @param offset the offset to start at
331
   * @param count the number of bytes in the array to use
332
   * @param encoding the name of the encoding to use
333
   * @throws NullPointerException if data or encoding is null
334
   * @throws IndexOutOfBoundsException if offset or count is incorrect
335
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
336
   * @throws UnsupportedEncodingException if encoding is not found
337
   * @throws Error if the decoding fails
338
   * @since 1.1
339
   */
340
  public String(byte[] data, int offset, int count, final String encoding)
341
    throws UnsupportedEncodingException
342
  {
343
    this(data, offset, count, stringToCharset(encoding));
344
  }
345
 
346
  /**
347
   * Wrapper method to convert exceptions resulting from
348
   * the selection of a {@link java.nio.charset.Charset} based on
349
   * a String.
350
   *
351
   * @throws UnsupportedEncodingException if encoding is not found
352
   */
353
  private static final Charset stringToCharset(final String encoding)
354
    throws UnsupportedEncodingException
355
  {
356
    try
357
      {
358
        return Charset.forName(encoding);
359
      }
360
    catch(IllegalCharsetNameException e)
361
      {
362
        throw new UnsupportedEncodingException("Encoding: "+encoding+
363
                                               " not found.");
364
      }
365
    catch(UnsupportedCharsetException e)
366
      {
367
        throw new UnsupportedEncodingException("Encoding: "+encoding+
368
                                               " not found.");
369
      }
370
  }
371
 
372
  /**
373
   * Creates a new String using the portion of the byte array starting at the
374
   * offset and ending at offset + count. Uses the specified encoding type
375
   * to decode the byte array, so the resulting string may be longer or
376
   * shorter than the byte array. For more decoding control, use
377
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
378
   * see {@link java.nio.charset.Charset}. Malformed input and unmappable
379
   * character sequences are replaced with the default replacement string
380
   * provided by the {@link java.nio.charset.Charset}.
381
   *
382
   * @param data byte array to copy
383
   * @param offset the offset to start at
384
   * @param count the number of bytes in the array to use
385
   * @param encoding the encoding to use
386
   * @throws NullPointerException if data or encoding is null
387
   * @throws IndexOutOfBoundsException if offset or count is incorrect
388
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
389
   * @since 1.6
390
   */
391
  public String(byte[] data, int offset, int count, Charset encoding)
392
  {
393
    if (offset < 0)
394
      throw new StringIndexOutOfBoundsException("offset: " + offset);
395
    if (count < 0)
396
      throw new StringIndexOutOfBoundsException("count: " + count);
397
    // equivalent to: offset + count < 0 || offset + count > data.length
398
    if (data.length - offset < count)
399
      throw new StringIndexOutOfBoundsException("offset + count: "
400
                                                + (offset + count));
401
    try
402
      {
403
        CharsetDecoder csd = encoding.newDecoder();
404
        csd.onMalformedInput(CodingErrorAction.REPLACE);
405
        csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
406
        CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
407
        if(cbuf.hasArray())
408
          {
409
            value = cbuf.array();
410
            this.offset = cbuf.position();
411
            this.count = cbuf.remaining();
412
          } else {
413
            // Doubt this will happen. But just in case.
414
            value = new char[cbuf.remaining()];
415
            cbuf.get(value);
416
            this.offset = 0;
417
            this.count = value.length;
418
          }
419
      }
420
    catch(CharacterCodingException e)
421
      {
422
        // This shouldn't ever happen.
423
        throw (InternalError) new InternalError().initCause(e);
424
      }
425
  }
426
 
427
  /**
428
   * Creates a new String using the byte array. Uses the specified encoding
429
   * type to decode the byte array, so the resulting string may be longer or
430
   * shorter than the byte array. For more decoding control, use
431
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
432
   * see {@link java.nio.charset.Charset}. The behavior is not specified if
433
   * the decoder encounters invalid characters; this implementation throws
434
   * an Error.
435
   *
436
   * @param data byte array to copy
437
   * @param encoding the name of the encoding to use
438
   * @throws NullPointerException if data or encoding is null
439
   * @throws UnsupportedEncodingException if encoding is not found
440
   * @throws Error if the decoding fails
441
   * @see #String(byte[], int, int, String)
442
   * @since 1.1
443
   */
444
  public String(byte[] data, String encoding)
445
    throws UnsupportedEncodingException
446
  {
447
    this(data, 0, data.length, encoding);
448
  }
449
 
450
  /**
451
   * Creates a new String using the byte array. Uses the specified encoding
452
   * type to decode the byte array, so the resulting string may be longer or
453
   * shorter than the byte array. For more decoding control, use
454
   * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
455
   * see {@link java.nio.charset.Charset}. Malformed input and unmappable
456
   * character sequences are replaced with the default replacement string
457
   * provided by the {@link java.nio.charset.Charset}.
458
   *
459
   * @param data byte array to copy
460
   * @param encoding the name of the encoding to use
461
   * @throws NullPointerException if data or encoding is null
462
   * @see #String(byte[], int, int, java.nio.Charset)
463
   * @since 1.6
464
   */
465
  public String(byte[] data, Charset encoding)
466
  {
467
    this(data, 0, data.length, encoding);
468
  }
469
 
470
  /**
471
   * Creates a new String using the portion of the byte array starting at the
472
   * offset and ending at offset + count. Uses the encoding of the platform's
473
   * default charset, so the resulting string may be longer or shorter than
474
   * the byte array. For more decoding control, use
475
   * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
476
   * if the decoder encounters invalid characters; this implementation throws
477
   * an Error.
478
   *
479
   * @param data byte array to copy
480
   * @param offset the offset to start at
481
   * @param count the number of bytes in the array to use
482
   * @throws NullPointerException if data is null
483
   * @throws IndexOutOfBoundsException if offset or count is incorrect
484
   * @throws Error if the decoding fails
485
   * @see #String(byte[], int, int, String)
486
   * @since 1.1
487
   */
488
  public String(byte[] data, int offset, int count)
489
  {
490
    if (offset < 0)
491
      throw new StringIndexOutOfBoundsException("offset: " + offset);
492
    if (count < 0)
493
      throw new StringIndexOutOfBoundsException("count: " + count);
494
    // equivalent to: offset + count < 0 || offset + count > data.length
495
    if (data.length - offset < count)
496
      throw new StringIndexOutOfBoundsException("offset + count: "
497
                                                + (offset + count));
498
    int o, c;
499
    char[] v;
500
    String encoding;
501
    try
502
        {
503
          encoding = System.getProperty("file.encoding");
504
          CharsetDecoder csd = Charset.forName(encoding).newDecoder();
505
          csd.onMalformedInput(CodingErrorAction.REPLACE);
506
          csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
507
          CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
508
          if(cbuf.hasArray())
509
            {
510
              v = cbuf.array();
511
              o = cbuf.position();
512
              c = cbuf.remaining();
513
            } else {
514
              // Doubt this will happen. But just in case.
515
              v = new char[cbuf.remaining()];
516
              cbuf.get(v);
517
              o = 0;
518
              c = v.length;
519
            }
520
        } catch(Exception ex){
521
            // If anything goes wrong (System property not set,
522
            // NIO provider not available, etc)
523
            // Default to the 'safe' encoding ISO8859_1
524
            v = new char[count];
525
            o = 0;
526
            c = count;
527
            for (int i=0;i<count;i++)
528
              v[i] = (char)data[offset+i];
529
        }
530
    this.value = v;
531
    this.offset = o;
532
    this.count = c;
533
  }
534
 
535
  /**
536
   * Creates a new String using the byte array. Uses the encoding of the
537
   * platform's default charset, so the resulting string may be longer or
538
   * shorter than the byte array. For more decoding control, use
539
   * {@link java.nio.charset.CharsetDecoder}.  The behavior is not specified
540
   * if the decoder encounters invalid characters; this implementation throws
541
   * an Error.
542
   *
543
   * @param data byte array to copy
544
   * @throws NullPointerException if data is null
545
   * @throws Error if the decoding fails
546
   * @see #String(byte[], int, int)
547
   * @see #String(byte[], int, int, String)
548
   * @since 1.1
549
   */
550
  public String(byte[] data)
551
  {
552
    this(data, 0, data.length);
553
  }
554
 
555
  /**
556
   * Creates a new String using the character sequence represented by
557
   * the StringBuffer. Subsequent changes to buf do not affect the String.
558
   *
559
   * @param buffer StringBuffer to copy
560
   * @throws NullPointerException if buffer is null
561
   */
562
  public String(StringBuffer buffer)
563
  {
564
    synchronized (buffer)
565
      {
566
        offset = 0;
567
        count = buffer.count;
568
        // Share unless buffer is 3/4 empty.
569
        if ((count << 2) < buffer.value.length)
570
          {
571
            value = new char[count];
572
            VMSystem.arraycopy(buffer.value, 0, value, 0, count);
573
          }
574
        else
575
          {
576
            buffer.shared = true;
577
            value = buffer.value;
578
          }
579
      }
580
  }
581
 
582
  /**
583
   * Creates a new String using the character sequence represented by
584
   * the StringBuilder. Subsequent changes to buf do not affect the String.
585
   *
586
   * @param buffer StringBuilder to copy
587
   * @throws NullPointerException if buffer is null
588
   */
589
  public String(StringBuilder buffer)
590
  {
591
    this(buffer.value, 0, buffer.count);
592
  }
593
 
594
  /**
595
   * Special constructor which can share an array when safe to do so.
596
   *
597
   * @param data the characters to copy
598
   * @param offset the location to start from
599
   * @param count the number of characters to use
600
   * @param dont_copy true if the array is trusted, and need not be copied
601
   * @throws NullPointerException if chars is null
602
   * @throws StringIndexOutOfBoundsException if bounds check fails
603
   */
604
  String(char[] data, int offset, int count, boolean dont_copy)
605
  {
606
    if (offset < 0)
607
      throw new StringIndexOutOfBoundsException("offset: " + offset);
608
    if (count < 0)
609
      throw new StringIndexOutOfBoundsException("count: " + count);
610
    // equivalent to: offset + count < 0 || offset + count > data.length
611
    if (data.length - offset < count)
612
      throw new StringIndexOutOfBoundsException("offset + count: "
613
                                                + (offset + count));
614
    if (dont_copy)
615
      {
616
        value = data;
617
        this.offset = offset;
618
      }
619
    else
620
      {
621
        value = new char[count];
622
        VMSystem.arraycopy(data, offset, value, 0, count);
623
        this.offset = 0;
624
      }
625
    this.count = count;
626
  }
627
 
628
  /**
629
   * Creates a new String containing the characters represented in the
630
   * given subarray of Unicode code points.
631
   * @param codePoints the entire array of code points
632
   * @param offset the start of the subarray
633
   * @param count the length of the subarray
634
   *
635
   * @throws IllegalArgumentException if an invalid code point is found
636
   * in the codePoints array
637
   * @throws IndexOutOfBoundsException if offset is negative or offset + count
638
   * is greater than the length of the array.
639
   */
640
  public String(int[] codePoints, int offset, int count)
641
  {
642
    // FIXME: This implementation appears to give correct internal
643
    // representation of the String because:
644
    //   - length() is correct
645
    //   - getting a char[] from toCharArray() and testing
646
    //     Character.codePointAt() on all the characters in that array gives
647
    //     the appropriate results
648
    // however printing the String gives incorrect results.  This may be
649
    // due to printing method errors (such as incorrectly looping through
650
    // the String one char at a time rather than one "character" at a time.
651
 
652
    if (offset < 0)
653
      throw new IndexOutOfBoundsException();
654
    int end = offset + count;
655
    int pos = 0;
656
    // This creates a char array that is long enough for all of the code
657
    // points to represent supplementary characters.  This is more than likely
658
    // a waste of storage, so we use it only temporarily and then copy the
659
    // used portion into the value array.
660
    char[] temp = new char[2 * codePoints.length];
661
    for (int i = offset; i < end; i++)
662
      {
663
        pos += Character.toChars(codePoints[i], temp, pos);
664
      }
665
    this.count = pos;
666
    this.value = new char[pos];
667
    System.arraycopy(temp, 0, value, 0, pos);
668
    this.offset = 0;
669
  }
670
 
671
  /**
672
   * Returns the number of characters contained in this String.
673
   *
674
   * @return the length of this String
675
   */
676
  public int length()
677
  {
678
    return count;
679
  }
680
 
681
  /**
682
   * Returns the character located at the specified index within this String.
683
   *
684
   * @param index position of character to return (base 0)
685
   * @return character located at position index
686
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= length()
687
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
688
   */
689
  public char charAt(int index)
690
  {
691
    if (index < 0 || index >= count)
692
      throw new StringIndexOutOfBoundsException(index);
693
    return value[offset + index];
694
  }
695
 
696
  /**
697
   * Get the code point at the specified index.  This is like #charAt(int),
698
   * but if the character is the start of a surrogate pair, and the
699
   * following character completes the pair, then the corresponding
700
   * supplementary code point is returned.
701
   * @param index the index of the codepoint to get, starting at 0
702
   * @return the codepoint at the specified index
703
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
704
   * @since 1.5
705
   */
706
  public synchronized int codePointAt(int index)
707
  {
708
    // Use the CharSequence overload as we get better range checking
709
    // this way.
710
    return Character.codePointAt(this, index);
711
  }
712
 
713
  /**
714
   * Get the code point before the specified index.  This is like
715
   * #codePointAt(int), but checks the characters at <code>index-1</code> and
716
   * <code>index-2</code> to see if they form a supplementary code point.
717
   * @param index the index just past the codepoint to get, starting at 0
718
   * @return the codepoint at the specified index
719
   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
720
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
721
   * @since 1.5
722
   */
723
  public synchronized int codePointBefore(int index)
724
  {
725
    // Use the CharSequence overload as we get better range checking
726
    // this way.
727
    return Character.codePointBefore(this, index);
728
  }
729
 
730
  /**
731
   * Copies characters from this String starting at a specified start index,
732
   * ending at a specified stop index, to a character array starting at
733
   * a specified destination begin index.
734
   *
735
   * @param srcBegin index to begin copying characters from this String
736
   * @param srcEnd index after the last character to be copied from this String
737
   * @param dst character array which this String is copied into
738
   * @param dstBegin index to start writing characters into dst
739
   * @throws NullPointerException if dst is null
740
   * @throws IndexOutOfBoundsException if any indices are out of bounds
741
   *         (while unspecified, source problems cause a
742
   *         StringIndexOutOfBoundsException, and dst problems cause an
743
   *         ArrayIndexOutOfBoundsException)
744
   */
745
  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
746
  {
747
    if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
748
      throw new StringIndexOutOfBoundsException();
749
    VMSystem.arraycopy(value, srcBegin + offset,
750
                     dst, dstBegin, srcEnd - srcBegin);
751
  }
752
 
753
  /**
754
   * Copies the low byte of each character from this String starting at a
755
   * specified start index, ending at a specified stop index, to a byte array
756
   * starting at a specified destination begin index.
757
   *
758
   * @param srcBegin index to being copying characters from this String
759
   * @param srcEnd index after the last character to be copied from this String
760
   * @param dst byte array which each low byte of this String is copied into
761
   * @param dstBegin index to start writing characters into dst
762
   * @throws NullPointerException if dst is null and copy length is non-zero
763
   * @throws IndexOutOfBoundsException if any indices are out of bounds
764
   *         (while unspecified, source problems cause a
765
   *         StringIndexOutOfBoundsException, and dst problems cause an
766
   *         ArrayIndexOutOfBoundsException)
767
   * @see #getBytes()
768
   * @see #getBytes(String)
769
   * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
770
   */
771
  public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)
772
  {
773
    if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
774
      throw new StringIndexOutOfBoundsException();
775
    int i = srcEnd - srcBegin;
776
    srcBegin += offset;
777
    while (--i >= 0)
778
      dst[dstBegin++] = (byte) value[srcBegin++];
779
  }
780
 
781
  /**
782
   * Converts the Unicode characters in this String to a byte array. Uses the
783
   * specified encoding method, so the result may be longer or shorter than
784
   * the String. For more encoding control, use
785
   * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
786
   * see {@link java.nio.charset.Charset}. Unsupported characters get
787
   * replaced by an encoding specific byte.
788
   *
789
   * @param enc encoding name
790
   * @return the resulting byte array
791
   * @throws NullPointerException if enc is null
792
   * @throws UnsupportedEncodingException if encoding is not supported
793
   * @since 1.1
794
   */
795
  public byte[] getBytes(final String enc)
796
    throws UnsupportedEncodingException
797
  {
798
    return getBytes(stringToCharset(enc));
799
  }
800
 
801
  /**
802
   * Converts the Unicode characters in this String to a byte array. Uses the
803
   * specified encoding method, so the result may be longer or shorter than
804
   * the String. For more encoding control, use
805
   * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
806
   * see {@link java.nio.charset.Charset}. Unsupported characters get
807
   * replaced by the {@link java.nio.charset.Charset}'s default replacement.
808
   *
809
   * @param enc encoding name
810
   * @return the resulting byte array
811
   * @throws NullPointerException if enc is null
812
   * @since 1.6
813
   */
814
  public byte[] getBytes(Charset enc)
815
  {
816
    try
817
      {
818
        CharsetEncoder cse = enc.newEncoder();
819
        cse.onMalformedInput(CodingErrorAction.REPLACE);
820
        cse.onUnmappableCharacter(CodingErrorAction.REPLACE);
821
        ByteBuffer bbuf = cse.encode(CharBuffer.wrap(value, offset, count));
822
        if(bbuf.hasArray())
823
          return bbuf.array();
824
 
825
        // Doubt this will happen. But just in case.
826
        byte[] bytes = new byte[bbuf.remaining()];
827
        bbuf.get(bytes);
828
        return bytes;
829
      }
830
    catch(CharacterCodingException e)
831
      {
832
        // This shouldn't ever happen.
833
        throw (InternalError) new InternalError().initCause(e);
834
      }
835
  }
836
 
837
  /**
838
   * Converts the Unicode characters in this String to a byte array. Uses the
839
   * encoding of the platform's default charset, so the result may be longer
840
   * or shorter than the String. For more encoding control, use
841
   * {@link java.nio.charset.CharsetEncoder}. Unsupported characters get
842
   * replaced by an encoding specific byte.
843
   *
844
   * @return the resulting byte array, or null on a problem
845
   * @since 1.1
846
   */
847
  public byte[] getBytes()
848
  {
849
      try
850
          {
851
              return getBytes(System.getProperty("file.encoding"));
852
          } catch(Exception e) {
853
              // XXX - Throw an error here?
854
              // For now, default to the 'safe' encoding.
855
              byte[] bytes = new byte[count];
856
              for(int i=0;i<count;i++)
857
                  bytes[i] = (byte)((value[offset+i] <= 0xFF)?
858
                                    value[offset+i]:'?');
859
              return bytes;
860
      }
861
  }
862
 
863
  /**
864
   * Predicate which compares anObject to this. This is true only for Strings
865
   * with the same character sequence.
866
   *
867
   * @param anObject the object to compare
868
   * @return true if anObject is semantically equal to this
869
   * @see #compareTo(String)
870
   * @see #equalsIgnoreCase(String)
871
   */
872
  public boolean equals(Object anObject)
873
  {
874
    if (! (anObject instanceof String))
875
      return false;
876
    String str2 = (String) anObject;
877
    if (count != str2.count)
878
      return false;
879
    if (value == str2.value && offset == str2.offset)
880
      return true;
881
    int i = count;
882
    int x = offset;
883
    int y = str2.offset;
884
    while (--i >= 0)
885
      if (value[x++] != str2.value[y++])
886
        return false;
887
    return true;
888
  }
889
 
890
  /**
891
   * Compares the given StringBuffer to this String. This is true if the
892
   * StringBuffer has the same content as this String at this moment.
893
   *
894
   * @param buffer the StringBuffer to compare to
895
   * @return true if StringBuffer has the same character sequence
896
   * @throws NullPointerException if the given StringBuffer is null
897
   * @since 1.4
898
   */
899
  public boolean contentEquals(StringBuffer buffer)
900
  {
901
    synchronized (buffer)
902
      {
903
        if (count != buffer.count)
904
          return false;
905
        if (value == buffer.value)
906
          return true; // Possible if shared.
907
        int i = count;
908
        int x = offset + count;
909
        while (--i >= 0)
910
          if (value[--x] != buffer.value[i])
911
            return false;
912
        return true;
913
      }
914
  }
915
 
916
  /**
917
   * Compares the given CharSequence to this String. This is true if
918
   * the CharSequence has the same content as this String at this
919
   * moment.
920
   *
921
   * @param seq the CharSequence to compare to
922
   * @return true if CharSequence has the same character sequence
923
   * @throws NullPointerException if the given CharSequence is null
924
   * @since 1.5
925
   */
926
  public boolean contentEquals(CharSequence seq)
927
  {
928
    if (seq.length() != count)
929
      return false;
930
    for (int i = 0; i < count; ++i)
931
      if (value[offset + i] != seq.charAt(i))
932
        return false;
933
    return true;
934
  }
935
 
936
  /**
937
   * Compares a String to this String, ignoring case. This does not handle
938
   * multi-character capitalization exceptions; instead the comparison is
939
   * made on a character-by-character basis, and is true if:<br><ul>
940
   * <li><code>c1 == c2</code></li>
941
   * <li><code>Character.toUpperCase(c1)
942
   *     == Character.toUpperCase(c2)</code></li>
943
   * <li><code>Character.toLowerCase(c1)
944
   *     == Character.toLowerCase(c2)</code></li>
945
   * </ul>
946
   *
947
   * @param anotherString String to compare to this String
948
   * @return true if anotherString is equal, ignoring case
949
   * @see #equals(Object)
950
   * @see Character#toUpperCase(char)
951
   * @see Character#toLowerCase(char)
952
   */
953
  public boolean equalsIgnoreCase(String anotherString)
954
  {
955
    if (anotherString == null || count != anotherString.count)
956
      return false;
957
    int i = count;
958
    int x = offset;
959
    int y = anotherString.offset;
960
    while (--i >= 0)
961
      {
962
        char c1 = value[x++];
963
        char c2 = anotherString.value[y++];
964
        // Note that checking c1 != c2 is redundant, but avoids method calls.
965
        if (c1 != c2
966
            && Character.toUpperCase(c1) != Character.toUpperCase(c2)
967
            && Character.toLowerCase(c1) != Character.toLowerCase(c2))
968
          return false;
969
      }
970
    return true;
971
  }
972
 
973
  /**
974
   * Compares this String and another String (case sensitive,
975
   * lexicographically). The result is less than 0 if this string sorts
976
   * before the other, 0 if they are equal, and greater than 0 otherwise.
977
   * After any common starting sequence is skipped, the result is
978
   * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
979
   * have characters remaining, or
980
   * <code>this.length() - anotherString.length()</code> if one string is
981
   * a subsequence of the other.
982
   *
983
   * @param anotherString the String to compare against
984
   * @return the comparison
985
   * @throws NullPointerException if anotherString is null
986
   */
987
  public int compareTo(String anotherString)
988
  {
989
    int i = Math.min(count, anotherString.count);
990
    int x = offset;
991
    int y = anotherString.offset;
992
    while (--i >= 0)
993
      {
994
        int result = value[x++] - anotherString.value[y++];
995
        if (result != 0)
996
          return result;
997
      }
998
    return count - anotherString.count;
999
  }
1000
 
1001
  /**
1002
   * Compares this String and another String (case insensitive). This
1003
   * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
1004
   * locale and multi-characater capitalization, and compares characters
1005
   * after performing
1006
   * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
1007
   * character of the string. This is unsatisfactory for locale-based
1008
   * comparison, in which case you should use {@link java.text.Collator}.
1009
   *
1010
   * @param str the string to compare against
1011
   * @return the comparison
1012
   * @see Collator#compare(String, String)
1013
   * @since 1.2
1014
   */
1015
  public int compareToIgnoreCase(String str)
1016
  {
1017
    int i = Math.min(count, str.count);
1018
    int x = offset;
1019
    int y = str.offset;
1020
    while (--i >= 0)
1021
      {
1022
        int result = Character.toLowerCase(Character.toUpperCase(value[x++]))
1023
          - Character.toLowerCase(Character.toUpperCase(str.value[y++]));
1024
        if (result != 0)
1025
          return result;
1026
      }
1027
    return count - str.count;
1028
  }
1029
 
1030
  /**
1031
   * Predicate which determines if this String matches another String
1032
   * starting at a specified offset for each String and continuing
1033
   * for a specified length. Indices out of bounds are harmless, and give
1034
   * a false result.
1035
   *
1036
   * @param toffset index to start comparison at for this String
1037
   * @param other String to compare region to this String
1038
   * @param ooffset index to start comparison at for other
1039
   * @param len number of characters to compare
1040
   * @return true if regions match (case sensitive)
1041
   * @throws NullPointerException if other is null
1042
   */
1043
  public boolean regionMatches(int toffset, String other, int ooffset, int len)
1044
  {
1045
    return regionMatches(false, toffset, other, ooffset, len);
1046
  }
1047
 
1048
  /**
1049
   * Predicate which determines if this String matches another String
1050
   * starting at a specified offset for each String and continuing
1051
   * for a specified length, optionally ignoring case. Indices out of bounds
1052
   * are harmless, and give a false result. Case comparisons are based on
1053
   * <code>Character.toLowerCase()</code> and
1054
   * <code>Character.toUpperCase()</code>, not on multi-character
1055
   * capitalization expansions.
1056
   *
1057
   * @param ignoreCase true if case should be ignored in comparision
1058
   * @param toffset index to start comparison at for this String
1059
   * @param other String to compare region to this String
1060
   * @param ooffset index to start comparison at for other
1061
   * @param len number of characters to compare
1062
   * @return true if regions match, false otherwise
1063
   * @throws NullPointerException if other is null
1064
   */
1065
  public boolean regionMatches(boolean ignoreCase, int toffset,
1066
                               String other, int ooffset, int len)
1067
  {
1068
    if (toffset < 0 || ooffset < 0 || toffset + len > count
1069
        || ooffset + len > other.count)
1070
      return false;
1071
    toffset += offset;
1072
    ooffset += other.offset;
1073
    while (--len >= 0)
1074
      {
1075
        char c1 = value[toffset++];
1076
        char c2 = other.value[ooffset++];
1077
        // Note that checking c1 != c2 is redundant when ignoreCase is true,
1078
        // but it avoids method calls.
1079
        if (c1 != c2
1080
            && (! ignoreCase
1081
                || (Character.toLowerCase(c1) != Character.toLowerCase(c2)
1082
                    && (Character.toUpperCase(c1)
1083
                        != Character.toUpperCase(c2)))))
1084
          return false;
1085
      }
1086
    return true;
1087
  }
1088
 
1089
  /**
1090
   * Predicate which determines if this String contains the given prefix,
1091
   * beginning comparison at toffset. The result is false if toffset is
1092
   * negative or greater than this.length(), otherwise it is the same as
1093
   * <code>this.substring(toffset).startsWith(prefix)</code>.
1094
   *
1095
   * @param prefix String to compare
1096
   * @param toffset offset for this String where comparison starts
1097
   * @return true if this String starts with prefix
1098
   * @throws NullPointerException if prefix is null
1099
   * @see #regionMatches(boolean, int, String, int, int)
1100
   */
1101
  public boolean startsWith(String prefix, int toffset)
1102
  {
1103
    return regionMatches(false, toffset, prefix, 0, prefix.count);
1104
  }
1105
 
1106
  /**
1107
   * Predicate which determines if this String starts with a given prefix.
1108
   * If the prefix is an empty String, true is returned.
1109
   *
1110
   * @param prefix String to compare
1111
   * @return true if this String starts with the prefix
1112
   * @throws NullPointerException if prefix is null
1113
   * @see #startsWith(String, int)
1114
   */
1115
  public boolean startsWith(String prefix)
1116
  {
1117
    return regionMatches(false, 0, prefix, 0, prefix.count);
1118
  }
1119
 
1120
  /**
1121
   * Predicate which determines if this String ends with a given suffix.
1122
   * If the suffix is an empty String, true is returned.
1123
   *
1124
   * @param suffix String to compare
1125
   * @return true if this String ends with the suffix
1126
   * @throws NullPointerException if suffix is null
1127
   * @see #regionMatches(boolean, int, String, int, int)
1128
   */
1129
  public boolean endsWith(String suffix)
1130
  {
1131
    return regionMatches(false, count - suffix.count, suffix, 0, suffix.count);
1132
  }
1133
 
1134
  /**
1135
   * Computes the hashcode for this String. This is done with int arithmetic,
1136
   * where ** represents exponentiation, by this formula:<br>
1137
   * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
1138
   *
1139
   * @return hashcode value of this String
1140
   */
1141
  public int hashCode()
1142
  {
1143
    if (cachedHashCode != 0)
1144
      return cachedHashCode;
1145
 
1146
    // Compute the hash code using a local variable to be reentrant.
1147
    int hashCode = 0;
1148
    int limit = count + offset;
1149
    for (int i = offset; i < limit; i++)
1150
      hashCode = hashCode * 31 + value[i];
1151
    return cachedHashCode = hashCode;
1152
  }
1153
 
1154
  /**
1155
   * Finds the first instance of a character in this String.
1156
   *
1157
   * @param ch character to find
1158
   * @return location (base 0) of the character, or -1 if not found
1159
   */
1160
  public int indexOf(int ch)
1161
  {
1162
    return indexOf(ch, 0);
1163
  }
1164
 
1165
  /**
1166
   * Finds the first instance of a character in this String, starting at
1167
   * a given index.  If starting index is less than 0, the search
1168
   * starts at the beginning of this String.  If the starting index
1169
   * is greater than the length of this String, -1 is returned.
1170
   *
1171
   * @param ch character to find
1172
   * @param fromIndex index to start the search
1173
   * @return location (base 0) of the character, or -1 if not found
1174
   */
1175
  public int indexOf(int ch, int fromIndex)
1176
  {
1177
    if ((char) ch != ch)
1178
      return -1;
1179
    if (fromIndex < 0)
1180
      fromIndex = 0;
1181
    int i = fromIndex + offset;
1182
    for ( ; fromIndex < count; fromIndex++)
1183
      if (value[i++] == ch)
1184
        return fromIndex;
1185
    return -1;
1186
  }
1187
 
1188
  /**
1189
   * Finds the last instance of a character in this String.
1190
   *
1191
   * @param ch character to find
1192
   * @return location (base 0) of the character, or -1 if not found
1193
   */
1194
  public int lastIndexOf(int ch)
1195
  {
1196
    return lastIndexOf(ch, count - 1);
1197
  }
1198
 
1199
  /**
1200
   * Finds the last instance of a character in this String, starting at
1201
   * a given index.  If starting index is greater than the maximum valid
1202
   * index, then the search begins at the end of this String.  If the
1203
   * starting index is less than zero, -1 is returned.
1204
   *
1205
   * @param ch character to find
1206
   * @param fromIndex index to start the search
1207
   * @return location (base 0) of the character, or -1 if not found
1208
   */
1209
  public int lastIndexOf(int ch, int fromIndex)
1210
  {
1211
    if ((char) ch != ch)
1212
      return -1;
1213
    if (fromIndex >= count)
1214
      fromIndex = count - 1;
1215
    int i = fromIndex + offset;
1216
    for ( ; fromIndex >= 0; fromIndex--)
1217
      if (value[i--] == ch)
1218
        return fromIndex;
1219
    return -1;
1220
  }
1221
 
1222
  /**
1223
   * Finds the first instance of a String in this String.
1224
   *
1225
   * @param str String to find
1226
   * @return location (base 0) of the String, or -1 if not found
1227
   * @throws NullPointerException if str is null
1228
   */
1229
  public int indexOf(String str)
1230
  {
1231
    return indexOf(str, 0);
1232
  }
1233
 
1234
  /**
1235
   * Finds the first instance of a String in this String, starting at
1236
   * a given index.  If starting index is less than 0, the search
1237
   * starts at the beginning of this String.  If the starting index
1238
   * is greater than the length of this String, -1 is returned.
1239
   *
1240
   * @param str String to find
1241
   * @param fromIndex index to start the search
1242
   * @return location (base 0) of the String, or -1 if not found
1243
   * @throws NullPointerException if str is null
1244
   */
1245
  public int indexOf(String str, int fromIndex)
1246
  {
1247
    if (fromIndex < 0)
1248
      fromIndex = 0;
1249
    int limit = count - str.count;
1250
    for ( ; fromIndex <= limit; fromIndex++)
1251
      if (regionMatches(fromIndex, str, 0, str.count))
1252
        return fromIndex;
1253
    return -1;
1254
  }
1255
 
1256
  /**
1257
   * Finds the last instance of a String in this String.
1258
   *
1259
   * @param str String to find
1260
   * @return location (base 0) of the String, or -1 if not found
1261
   * @throws NullPointerException if str is null
1262
   */
1263
  public int lastIndexOf(String str)
1264
  {
1265
    return lastIndexOf(str, count - str.count);
1266
  }
1267
 
1268
  /**
1269
   * Finds the last instance of a String in this String, starting at
1270
   * a given index.  If starting index is greater than the maximum valid
1271
   * index, then the search begins at the end of this String.  If the
1272
   * starting index is less than zero, -1 is returned.
1273
   *
1274
   * @param str String to find
1275
   * @param fromIndex index to start the search
1276
   * @return location (base 0) of the String, or -1 if not found
1277
   * @throws NullPointerException if str is null
1278
   */
1279
  public int lastIndexOf(String str, int fromIndex)
1280
  {
1281
    fromIndex = Math.min(fromIndex, count - str.count);
1282
    for ( ; fromIndex >= 0; fromIndex--)
1283
      if (regionMatches(fromIndex, str, 0, str.count))
1284
        return fromIndex;
1285
    return -1;
1286
  }
1287
 
1288
  /**
1289
   * Creates a substring of this String, starting at a specified index
1290
   * and ending at the end of this String.
1291
   *
1292
   * @param begin index to start substring (base 0)
1293
   * @return new String which is a substring of this String
1294
   * @throws IndexOutOfBoundsException if begin &lt; 0 || begin &gt; length()
1295
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
1296
   */
1297
  public String substring(int begin)
1298
  {
1299
    return substring(begin, count);
1300
  }
1301
 
1302
  /**
1303
   * Creates a substring of this String, starting at a specified index
1304
   * and ending at one character before a specified index.
1305
   *
1306
   * @param beginIndex index to start substring (inclusive, base 0)
1307
   * @param endIndex index to end at (exclusive)
1308
   * @return new String which is a substring of this String
1309
   * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
1310
   *         || begin &gt; end (while unspecified, this is a
1311
   *         StringIndexOutOfBoundsException)
1312
   */
1313
  public String substring(int beginIndex, int endIndex)
1314
  {
1315
    if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
1316
      throw new StringIndexOutOfBoundsException();
1317
    if (beginIndex == 0 && endIndex == count)
1318
      return this;
1319
    int len = endIndex - beginIndex;
1320
    // Package constructor avoids an array copy.
1321
    return new String(value, beginIndex + offset, len,
1322
                      (len << 2) >= value.length);
1323
  }
1324
 
1325
  /**
1326
   * Creates a substring of this String, starting at a specified index
1327
   * and ending at one character before a specified index. This behaves like
1328
   * <code>substring(begin, end)</code>.
1329
   *
1330
   * @param begin index to start substring (inclusive, base 0)
1331
   * @param end index to end at (exclusive)
1332
   * @return new String which is a substring of this String
1333
   * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
1334
   *         || begin &gt; end
1335
   * @since 1.4
1336
   */
1337
  public CharSequence subSequence(int begin, int end)
1338
  {
1339
    return substring(begin, end);
1340
  }
1341
 
1342
  /**
1343
   * Concatenates a String to this String. This results in a new string unless
1344
   * one of the two originals is "".
1345
   *
1346
   * @param str String to append to this String
1347
   * @return newly concatenated String
1348
   * @throws NullPointerException if str is null
1349
   */
1350
  public String concat(String str)
1351
  {
1352
    if (str.count == 0)
1353
      return this;
1354
    if (count == 0)
1355
      return str;
1356
    char[] newStr = new char[count + str.count];
1357
    VMSystem.arraycopy(value, offset, newStr, 0, count);
1358
    VMSystem.arraycopy(str.value, str.offset, newStr, count, str.count);
1359
    // Package constructor avoids an array copy.
1360
    return new String(newStr, 0, newStr.length, true);
1361
  }
1362
 
1363
  /**
1364
   * Replaces every instance of a character in this String with a new
1365
   * character. If no replacements occur, this is returned.
1366
   *
1367
   * @param oldChar the old character to replace
1368
   * @param newChar the new character
1369
   * @return new String with all instances of oldChar replaced with newChar
1370
   */
1371
  public String replace(char oldChar, char newChar)
1372
  {
1373
    if (oldChar == newChar)
1374
      return this;
1375
    int i = count;
1376
    int x = offset - 1;
1377
    while (--i >= 0)
1378
      if (value[++x] == oldChar)
1379
        break;
1380
    if (i < 0)
1381
      return this;
1382
    char[] newStr = toCharArray();
1383
    newStr[x - offset] = newChar;
1384
    while (--i >= 0)
1385
      if (value[++x] == oldChar)
1386
        newStr[x - offset] = newChar;
1387
    // Package constructor avoids an array copy.
1388
    return new String(newStr, 0, count, true);
1389
  }
1390
 
1391
  /**
1392
   * Test if this String matches a regular expression. This is shorthand for
1393
   * <code>{@link Pattern}.matches(regex, this)</code>.
1394
   *
1395
   * @param regex the pattern to match
1396
   * @return true if the pattern matches
1397
   * @throws NullPointerException if regex is null
1398
   * @throws PatternSyntaxException if regex is invalid
1399
   * @see Pattern#matches(String, CharSequence)
1400
   * @since 1.4
1401
   */
1402
  public boolean matches(String regex)
1403
  {
1404
    return Pattern.matches(regex, this);
1405
  }
1406
 
1407
  /**
1408
   * Replaces the first substring match of the regular expression with a
1409
   * given replacement. This is shorthand for <code>{@link Pattern}
1410
   *   .compile(regex).matcher(this).replaceFirst(replacement)</code>.
1411
   *
1412
   * @param regex the pattern to match
1413
   * @param replacement the replacement string
1414
   * @return the modified string
1415
   * @throws NullPointerException if regex or replacement is null
1416
   * @throws PatternSyntaxException if regex is invalid
1417
   * @see #replaceAll(String, String)
1418
   * @see Pattern#compile(String)
1419
   * @see Pattern#matcher(CharSequence)
1420
   * @see Matcher#replaceFirst(String)
1421
   * @since 1.4
1422
   */
1423
  public String replaceFirst(String regex, String replacement)
1424
  {
1425
    return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
1426
  }
1427
 
1428
  /**
1429
   * Replaces all matching substrings of the regular expression with a
1430
   * given replacement. This is shorthand for <code>{@link Pattern}
1431
   *   .compile(regex).matcher(this).replaceAll(replacement)</code>.
1432
   *
1433
   * @param regex the pattern to match
1434
   * @param replacement the replacement string
1435
   * @return the modified string
1436
   * @throws NullPointerException if regex or replacement is null
1437
   * @throws PatternSyntaxException if regex is invalid
1438
   * @see #replaceFirst(String, String)
1439
   * @see Pattern#compile(String)
1440
   * @see Pattern#matcher(CharSequence)
1441
   * @see Matcher#replaceAll(String)
1442
   * @since 1.4
1443
   */
1444
  public String replaceAll(String regex, String replacement)
1445
  {
1446
    return Pattern.compile(regex).matcher(this).replaceAll(replacement);
1447
  }
1448
 
1449
  /**
1450
   * Split this string around the matches of a regular expression. Each
1451
   * element of the returned array is the largest block of characters not
1452
   * terminated by the regular expression, in the order the matches are found.
1453
   *
1454
   * <p>The limit affects the length of the array. If it is positive, the
1455
   * array will contain at most n elements (n - 1 pattern matches). If
1456
   * negative, the array length is unlimited, but there can be trailing empty
1457
   * entries. if 0, the array length is unlimited, and trailing empty entries
1458
   * are discarded.
1459
   *
1460
   * <p>For example, splitting "boo:and:foo" yields:<br>
1461
   * <table border=0>
1462
   * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
1463
   * <tr><td>":"</td>   <td>2</td>  <td>{ "boo", "and:foo" }</td></tr>
1464
   * <tr><td>":"</td>   <td>t</td>  <td>{ "boo", "and", "foo" }</td></tr>
1465
   * <tr><td>":"</td>   <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
1466
   * <tr><td>"o"</td>   <td>5</td>  <td>{ "b", "", ":and:f", "", "" }</td></tr>
1467
   * <tr><td>"o"</td>   <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
1468
   * <tr><td>"o"</td>   <td>0</td>  <td>{ "b", "", ":and:f" }</td></tr>
1469
   * </table>
1470
   *
1471
   * <p>This is shorthand for
1472
   * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
1473
   *
1474
   * @param regex the pattern to match
1475
   * @param limit the limit threshold
1476
   * @return the array of split strings
1477
   * @throws NullPointerException if regex or replacement is null
1478
   * @throws PatternSyntaxException if regex is invalid
1479
   * @see Pattern#compile(String)
1480
   * @see Pattern#split(CharSequence, int)
1481
   * @since 1.4
1482
   */
1483
  public String[] split(String regex, int limit)
1484
  {
1485
    return Pattern.compile(regex).split(this, limit);
1486
  }
1487
 
1488
  /**
1489
   * Split this string around the matches of a regular expression. Each
1490
   * element of the returned array is the largest block of characters not
1491
   * terminated by the regular expression, in the order the matches are found.
1492
   * The array length is unlimited, and trailing empty entries are discarded,
1493
   * as though calling <code>split(regex, 0)</code>.
1494
   *
1495
   * @param regex the pattern to match
1496
   * @return the array of split strings
1497
   * @throws NullPointerException if regex or replacement is null
1498
   * @throws PatternSyntaxException if regex is invalid
1499
   * @see #split(String, int)
1500
   * @see Pattern#compile(String)
1501
   * @see Pattern#split(CharSequence, int)
1502
   * @since 1.4
1503
   */
1504
  public String[] split(String regex)
1505
  {
1506
    return Pattern.compile(regex).split(this, 0);
1507
  }
1508
 
1509
  /**
1510
   * Convert string to lower case for a Turkish locale that requires special
1511
   * handling of '\u0049'
1512
   */
1513
  private String toLowerCaseTurkish()
1514
  {
1515
    // First, see if the current string is already lower case.
1516
    int i = count;
1517
    int x = offset - 1;
1518
    while (--i >= 0)
1519
      {
1520
        char ch = value[++x];
1521
        if ((ch == '\u0049') || ch != Character.toLowerCase(ch))
1522
          break;
1523
      }
1524
    if (i < 0)
1525
      return this;
1526
 
1527
    // Now we perform the conversion. Fortunately, there are no multi-character
1528
    // lowercase expansions in Unicode 3.0.0.
1529
    char[] newStr = new char[count];
1530
    VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
1531
    do
1532
      {
1533
        char ch = value[x];
1534
        // Hardcoded special case.
1535
        if (ch != '\u0049')
1536
          {
1537
            newStr[x - offset] = Character.toLowerCase(ch);
1538
          }
1539
        else
1540
          {
1541
            newStr[x - offset] = '\u0131';
1542
          }
1543
        x++;
1544
      }
1545
    while (--i >= 0);
1546
    // Package constructor avoids an array copy.
1547
    return new String(newStr, 0, count, true);
1548
  }
1549
 
1550
  /**
1551
   * Lowercases this String according to a particular locale. This uses
1552
   * Unicode's special case mappings, as applied to the given Locale, so the
1553
   * resulting string may be a different length.
1554
   *
1555
   * @param loc locale to use
1556
   * @return new lowercased String, or this if no characters were lowercased
1557
   * @throws NullPointerException if loc is null
1558
   * @see #toUpperCase(Locale)
1559
   * @since 1.1
1560
   */
1561
  public String toLowerCase(Locale loc)
1562
  {
1563
    // First, see if the current string is already lower case.
1564
 
1565
    // Is loc turkish? String equality test is ok as Locale.language is interned
1566
    if ("tr" == loc.getLanguage())
1567
      {
1568
        return toLowerCaseTurkish();
1569
      }
1570
    else
1571
      {
1572
        int i = count;
1573
        int x = offset - 1;
1574
        while (--i >= 0)
1575
          {
1576
            char ch = value[++x];
1577
            if (ch != Character.toLowerCase(ch))
1578
              break;
1579
          }
1580
        if (i < 0)
1581
          return this;
1582
 
1583
        // Now we perform the conversion. Fortunately, there are no
1584
        // multi-character lowercase expansions in Unicode 3.0.0.
1585
        char[] newStr = new char[count];
1586
        VMSystem.arraycopy(value, offset, newStr, 0, x - offset);
1587
        do
1588
          {
1589
            char ch = value[x];
1590
            // Hardcoded special case.
1591
            newStr[x - offset] = Character.toLowerCase(ch);
1592
            x++;
1593
          }
1594
        while (--i >= 0);
1595
        // Package constructor avoids an array copy.
1596
        return new String(newStr, 0, count, true);
1597
     }
1598
  }
1599
 
1600
  /**
1601
   * Lowercases this String. This uses Unicode's special case mappings, as
1602
   * applied to the platform's default Locale, so the resulting string may
1603
   * be a different length.
1604
   *
1605
   * @return new lowercased String, or this if no characters were lowercased
1606
   * @see #toLowerCase(Locale)
1607
   * @see #toUpperCase()
1608
   */
1609
  public String toLowerCase()
1610
  {
1611
    return toLowerCase(Locale.getDefault());
1612
  }
1613
 
1614
  /**
1615
   * Uppercase this string for a Turkish locale
1616
   */
1617
  private String toUpperCaseTurkish()
1618
  {
1619
    // First, see how many characters we have to grow by, as well as if the
1620
    // current string is already upper case.
1621
    int expand = 0;
1622
    boolean unchanged = true;
1623
    int i = count;
1624
    int x = i + offset;
1625
    while (--i >= 0)
1626
      {
1627
        char ch = value[--x];
1628
        expand += upperCaseExpansion(ch);
1629
        unchanged = (unchanged && expand == 0
1630
                     && ch != '\u0069'
1631
                     && ch == Character.toUpperCase(ch));
1632
      }
1633
    if (unchanged)
1634
      return this;
1635
 
1636
    // Now we perform the conversion.
1637
    i = count;
1638
    if (expand == 0)
1639
      {
1640
        char[] newStr = new char[count];
1641
        VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
1642
        while (--i >= 0)
1643
          {
1644
            char ch = value[x];
1645
            // Hardcoded special case.
1646
            if (ch != '\u0069')
1647
              {
1648
                newStr[x - offset] = Character.toUpperCase(ch);
1649
              }
1650
            else
1651
              {
1652
                newStr[x - offset] = '\u0130';
1653
              }
1654
            x++;
1655
          }
1656
        // Package constructor avoids an array copy.
1657
        return new String(newStr, 0, count, true);
1658
      }
1659
 
1660
    // Expansion is necessary.
1661
    char[] newStr = new char[count + expand];
1662
    int j = 0;
1663
    while (--i >= 0)
1664
      {
1665
        char ch = value[x++];
1666
        // Hardcoded special case.
1667
        if (ch == '\u0069')
1668
          {
1669
            newStr[j++] = '\u0130';
1670
            continue;
1671
          }
1672
        expand = upperCaseExpansion(ch);
1673
        if (expand > 0)
1674
          {
1675
            int index = upperCaseIndex(ch);
1676
            while (expand-- >= 0)
1677
              newStr[j++] = upperExpand[index++];
1678
          }
1679
        else
1680
          newStr[j++] = Character.toUpperCase(ch);
1681
      }
1682
    // Package constructor avoids an array copy.
1683
    return new String(newStr, 0, newStr.length, true);
1684
  }
1685
 
1686
  /**
1687
   * Uppercases this String according to a particular locale. This uses
1688
   * Unicode's special case mappings, as applied to the given Locale, so the
1689
   * resulting string may be a different length.
1690
   *
1691
   * @param loc locale to use
1692
   * @return new uppercased String, or this if no characters were uppercased
1693
   * @throws NullPointerException if loc is null
1694
   * @see #toLowerCase(Locale)
1695
   * @since 1.1
1696
   */
1697
  public String toUpperCase(Locale loc)
1698
  {
1699
    // First, see how many characters we have to grow by, as well as if the
1700
    // current string is already upper case.
1701
 
1702
    // Is loc turkish? String equality test is ok as Locale.language is interned
1703
    if ("tr" == loc.getLanguage())
1704
      {
1705
        return toUpperCaseTurkish();
1706
      }
1707
    else
1708
      {
1709
        int expand = 0;
1710
        boolean unchanged = true;
1711
        int i = count;
1712
        int x = i + offset;
1713
        while (--i >= 0)
1714
          {
1715
            char ch = value[--x];
1716
            expand += upperCaseExpansion(ch);
1717
            unchanged = (unchanged && expand == 0
1718
                         && ch == Character.toUpperCase(ch));
1719
          }
1720
        if (unchanged)
1721
          return this;
1722
 
1723
        // Now we perform the conversion.
1724
        i = count;
1725
        if (expand == 0)
1726
          {
1727
            char[] newStr = new char[count];
1728
            VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
1729
            while (--i >= 0)
1730
              {
1731
                char ch = value[x];
1732
                newStr[x - offset] = Character.toUpperCase(ch);
1733
                x++;
1734
              }
1735
            // Package constructor avoids an array copy.
1736
            return new String(newStr, 0, count, true);
1737
          }
1738
 
1739
        // Expansion is necessary.
1740
        char[] newStr = new char[count + expand];
1741
        int j = 0;
1742
        while (--i >= 0)
1743
          {
1744
            char ch = value[x++];
1745
            expand = upperCaseExpansion(ch);
1746
            if (expand > 0)
1747
              {
1748
                int index = upperCaseIndex(ch);
1749
                while (expand-- >= 0)
1750
                  newStr[j++] = upperExpand[index++];
1751
              }
1752
            else
1753
              newStr[j++] = Character.toUpperCase(ch);
1754
          }
1755
        // Package constructor avoids an array copy.
1756
        return new String(newStr, 0, newStr.length, true);
1757
      }
1758
  }
1759
  /**
1760
   * Uppercases this String. This uses Unicode's special case mappings, as
1761
   * applied to the platform's default Locale, so the resulting string may
1762
   * be a different length.
1763
   *
1764
   * @return new uppercased String, or this if no characters were uppercased
1765
   * @see #toUpperCase(Locale)
1766
   * @see #toLowerCase()
1767
   */
1768
  public String toUpperCase()
1769
  {
1770
    return toUpperCase(Locale.getDefault());
1771
  }
1772
 
1773
  /**
1774
   * Trims all characters less than or equal to <code>'\u0020'</code>
1775
   * (<code>' '</code>) from the beginning and end of this String. This
1776
   * includes many, but not all, ASCII control characters, and all
1777
   * {@link Character#isWhitespace(char)}.
1778
   *
1779
   * @return new trimmed String, or this if nothing trimmed
1780
   */
1781
  public String trim()
1782
  {
1783
    int limit = count + offset;
1784
    if (count == 0 || (value[offset] > '\u0020'
1785
                       && value[limit - 1] > '\u0020'))
1786
      return this;
1787
    int begin = offset;
1788
    do
1789
      if (begin == limit)
1790
        return "";
1791
    while (value[begin++] <= '\u0020');
1792
 
1793
    int end = limit;
1794
    while (value[--end] <= '\u0020')
1795
      ;
1796
    return substring(begin - offset - 1, end - offset + 1);
1797
  }
1798
 
1799
  /**
1800
   * Returns this, as it is already a String!
1801
   *
1802
   * @return this
1803
   */
1804
  public String toString()
1805
  {
1806
    return this;
1807
  }
1808
 
1809
  /**
1810
   * Copies the contents of this String into a character array. Subsequent
1811
   * changes to the array do not affect the String.
1812
   *
1813
   * @return character array copying the String
1814
   */
1815
  public char[] toCharArray()
1816
  {
1817
    char[] copy = new char[count];
1818
    VMSystem.arraycopy(value, offset, copy, 0, count);
1819
    return copy;
1820
  }
1821
 
1822
  /**
1823
   * Returns a String representation of an Object. This is "null" if the
1824
   * object is null, otherwise it is <code>obj.toString()</code> (which
1825
   * can be null).
1826
   *
1827
   * @param obj the Object
1828
   * @return the string conversion of obj
1829
   */
1830
  public static String valueOf(Object obj)
1831
  {
1832
    return obj == null ? "null" : obj.toString();
1833
  }
1834
 
1835
  /**
1836
   * Returns a String representation of a character array. Subsequent
1837
   * changes to the array do not affect the String.
1838
   *
1839
   * @param data the character array
1840
   * @return a String containing the same character sequence as data
1841
   * @throws NullPointerException if data is null
1842
   * @see #valueOf(char[], int, int)
1843
   * @see #String(char[])
1844
   */
1845
  public static String valueOf(char[] data)
1846
  {
1847
    return valueOf (data, 0, data.length);
1848
  }
1849
 
1850
  /**
1851
   * Returns a String representing the character sequence of the char array,
1852
   * starting at the specified offset, and copying chars up to the specified
1853
   * count. Subsequent changes to the array do not affect the String.
1854
   *
1855
   * @param data character array
1856
   * @param offset position (base 0) to start copying out of data
1857
   * @param count the number of characters from data to copy
1858
   * @return String containing the chars from data[offset..offset+count]
1859
   * @throws NullPointerException if data is null
1860
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
1861
   *         || offset + count &gt; data.length)
1862
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
1863
   * @see #String(char[], int, int)
1864
   */
1865
  public static String valueOf(char[] data, int offset, int count)
1866
  {
1867
    return new String(data, offset, count, false);
1868
  }
1869
 
1870
  /**
1871
   * Returns a String representing the character sequence of the char array,
1872
   * starting at the specified offset, and copying chars up to the specified
1873
   * count. Subsequent changes to the array do not affect the String.
1874
   *
1875
   * @param data character array
1876
   * @param offset position (base 0) to start copying out of data
1877
   * @param count the number of characters from data to copy
1878
   * @return String containing the chars from data[offset..offset+count]
1879
   * @throws NullPointerException if data is null
1880
   * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
1881
   *         || offset + count &lt; 0 (overflow)
1882
   *         || offset + count &lt; 0 (overflow)
1883
   *         || offset + count &gt; data.length)
1884
   *         (while unspecified, this is a StringIndexOutOfBoundsException)
1885
   * @see #String(char[], int, int)
1886
   */
1887
  public static String copyValueOf(char[] data, int offset, int count)
1888
  {
1889
    return new String(data, offset, count, false);
1890
  }
1891
 
1892
  /**
1893
   * Returns a String representation of a character array. Subsequent
1894
   * changes to the array do not affect the String.
1895
   *
1896
   * @param data the character array
1897
   * @return a String containing the same character sequence as data
1898
   * @throws NullPointerException if data is null
1899
   * @see #copyValueOf(char[], int, int)
1900
   * @see #String(char[])
1901
   */
1902
  public static String copyValueOf(char[] data)
1903
  {
1904
    return copyValueOf (data, 0, data.length);
1905
  }
1906
 
1907
  /**
1908
   * Returns a String representing a boolean.
1909
   *
1910
   * @param b the boolean
1911
   * @return "true" if b is true, else "false"
1912
   */
1913
  public static String valueOf(boolean b)
1914
  {
1915
    return b ? "true" : "false";
1916
  }
1917
 
1918
  /**
1919
   * Returns a String representing a character.
1920
   *
1921
   * @param c the character
1922
   * @return String containing the single character c
1923
   */
1924
  public static String valueOf(char c)
1925
  {
1926
    // Package constructor avoids an array copy.
1927
    return new String(new char[] { c }, 0, 1, true);
1928
  }
1929
 
1930
  /**
1931
   * Returns a String representing an integer.
1932
   *
1933
   * @param i the integer
1934
   * @return String containing the integer in base 10
1935
   * @see Integer#toString(int)
1936
   */
1937
  public static String valueOf(int i)
1938
  {
1939
    // See Integer to understand why we call the two-arg variant.
1940
    return Integer.toString(i, 10);
1941
  }
1942
 
1943
  /**
1944
   * Returns a String representing a long.
1945
   *
1946
   * @param l the long
1947
   * @return String containing the long in base 10
1948
   * @see Long#toString(long)
1949
   */
1950
  public static String valueOf(long l)
1951
  {
1952
    return Long.toString(l);
1953
  }
1954
 
1955
  /**
1956
   * Returns a String representing a float.
1957
   *
1958
   * @param f the float
1959
   * @return String containing the float
1960
   * @see Float#toString(float)
1961
   */
1962
  public static String valueOf(float f)
1963
  {
1964
    return Float.toString(f);
1965
  }
1966
 
1967
  /**
1968
   * Returns a String representing a double.
1969
   *
1970
   * @param d the double
1971
   * @return String containing the double
1972
   * @see Double#toString(double)
1973
   */
1974
  public static String valueOf(double d)
1975
  {
1976
    return Double.toString(d);
1977
  }
1978
 
1979
 
1980
  /** @since 1.5 */
1981
  public static String format(Locale locale, String format, Object... args)
1982
  {
1983
    Formatter f = new Formatter(locale);
1984
    return f.format(format, args).toString();
1985
  }
1986
 
1987
  /** @since 1.5 */
1988
  public static String format(String format, Object... args)
1989
  {
1990
    return format(Locale.getDefault(), format, args);
1991
  }
1992
 
1993
  /**
1994
   * If two Strings are considered equal, by the equals() method,
1995
   * then intern() will return the same String instance. ie.
1996
   * if (s1.equals(s2)) then (s1.intern() == s2.intern()).
1997
   * All string literals and string-valued constant expressions
1998
   * are already interned.
1999
   *
2000
   * @return the interned String
2001
   */
2002
  public String intern()
2003
  {
2004
    return VMString.intern(this);
2005
  }
2006
 
2007
  /**
2008
   * Return the number of code points between two indices in the
2009
   * <code>String</code>.  An unpaired surrogate counts as a
2010
   * code point for this purpose.  Characters outside the indicated
2011
   * range are not examined, even if the range ends in the middle of a
2012
   * surrogate pair.
2013
   *
2014
   * @param start the starting index
2015
   * @param end one past the ending index
2016
   * @return the number of code points
2017
   * @since 1.5
2018
   */
2019
  public synchronized int codePointCount(int start, int end)
2020
  {
2021
    if (start < 0 || end > count || start > end)
2022
      throw new StringIndexOutOfBoundsException();
2023
 
2024
    start += offset;
2025
    end += offset;
2026
    int count = 0;
2027
    while (start < end)
2028
      {
2029
        char base = value[start];
2030
        if (base < Character.MIN_HIGH_SURROGATE
2031
            || base > Character.MAX_HIGH_SURROGATE
2032
            || start == end
2033
            || start == count
2034
            || value[start + 1] < Character.MIN_LOW_SURROGATE
2035
            || value[start + 1] > Character.MAX_LOW_SURROGATE)
2036
          {
2037
            // Nothing.
2038
          }
2039
        else
2040
          {
2041
            // Surrogate pair.
2042
            ++start;
2043
          }
2044
        ++start;
2045
        ++count;
2046
      }
2047
    return count;
2048
  }
2049
 
2050
  /**
2051
   * Helper function used to detect which characters have a multi-character
2052
   * uppercase expansion. Note that this is only used in locations which
2053
   * track one-to-many capitalization (java.lang.Character does not do this).
2054
   * As of Unicode 3.0.0, the result is limited in the range 0 to 2, as the
2055
   * longest uppercase expansion is three characters (a growth of 2 from the
2056
   * lowercase character).
2057
   *
2058
   * @param ch the char to check
2059
   * @return the number of characters to add when converting to uppercase
2060
   * @see CharData#DIRECTION
2061
   * @see CharData#UPPER_SPECIAL
2062
   * @see #toUpperCase(Locale)
2063
   */
2064
  private static int upperCaseExpansion(char ch)
2065
  {
2066
    return Character.direction[0][Character.readCodePoint((int)ch) >> 7] & 3;
2067
  }
2068
 
2069
  /**
2070
   * Helper function used to locate the offset in upperExpand given a
2071
   * character with a multi-character expansion. The binary search is
2072
   * optimized under the assumption that this method will only be called on
2073
   * characters which exist in upperSpecial.
2074
   *
2075
   * @param ch the char to check
2076
   * @return the index where its expansion begins
2077
   * @see CharData#UPPER_SPECIAL
2078
   * @see CharData#UPPER_EXPAND
2079
   * @see #toUpperCase(Locale)
2080
   */
2081
  private static int upperCaseIndex(char ch)
2082
  {
2083
    // Simple binary search for the correct character.
2084
    int low = 0;
2085
    int hi = upperSpecial.length - 2;
2086
    int mid = ((low + hi) >> 2) << 1;
2087
    char c = upperSpecial[mid];
2088
    while (ch != c)
2089
      {
2090
        if (ch < c)
2091
          hi = mid - 2;
2092
        else
2093
          low = mid + 2;
2094
        mid = ((low + hi) >> 2) << 1;
2095
        c = upperSpecial[mid];
2096
      }
2097
    return upperSpecial[mid + 1];
2098
  }
2099
 
2100
  /**
2101
   * Returns the value array of the given string if it is zero based or a
2102
   * copy of it that is zero based (stripping offset and making length equal
2103
   * to count). Used for accessing the char[]s of gnu.java.lang.CharData.
2104
   * Package private for use in Character.
2105
   */
2106
  static char[] zeroBasedStringValue(String s)
2107
  {
2108
    char[] value;
2109
 
2110
    if (s.offset == 0 && s.count == s.value.length)
2111
      value = s.value;
2112
    else
2113
      {
2114
        int count = s.count;
2115
        value = new char[count];
2116
        VMSystem.arraycopy(s.value, s.offset, value, 0, count);
2117
      }
2118
 
2119
    return value;
2120
  }
2121
 
2122
  /**
2123
   * Returns true iff this String contains the sequence of Characters
2124
   * described in s.
2125
   * @param s the CharSequence
2126
   * @return true iff this String contains s
2127
   *
2128
   * @since 1.5
2129
   */
2130
  public boolean contains (CharSequence s)
2131
  {
2132
    return this.indexOf(s.toString()) != -1;
2133
  }
2134
 
2135
  /**
2136
   * Returns a string that is this string with all instances of the sequence
2137
   * represented by <code>target</code> replaced by the sequence in
2138
   * <code>replacement</code>.
2139
   * @param target the sequence to be replaced
2140
   * @param replacement the sequence used as the replacement
2141
   * @return the string constructed as above
2142
   */
2143
  public String replace (CharSequence target, CharSequence replacement)
2144
  {
2145
    String targetString = target.toString();
2146
    String replaceString = replacement.toString();
2147
    int targetLength = target.length();
2148
    int replaceLength = replacement.length();
2149
 
2150
    int startPos = this.indexOf(targetString);
2151
    CPStringBuilder result = new CPStringBuilder(this);
2152
    while (startPos != -1)
2153
      {
2154
        // Replace the target with the replacement
2155
        result.replace(startPos, startPos + targetLength, replaceString);
2156
 
2157
        // Search for a new occurrence of the target
2158
        startPos = result.indexOf(targetString, startPos + replaceLength);
2159
      }
2160
    return result.toString();
2161
  }
2162
 
2163
  /**
2164
   * Return the index into this String that is offset from the given index by
2165
   * <code>codePointOffset</code> code points.
2166
   * @param index the index at which to start
2167
   * @param codePointOffset the number of code points to offset
2168
   * @return the index into this String that is <code>codePointOffset</code>
2169
   * code points offset from <code>index</code>.
2170
   *
2171
   * @throws IndexOutOfBoundsException if index is negative or larger than the
2172
   * length of this string.
2173
   * @throws IndexOutOfBoundsException if codePointOffset is positive and the
2174
   * substring starting with index has fewer than codePointOffset code points.
2175
   * @throws IndexOutOfBoundsException if codePointOffset is negative and the
2176
   * substring ending with index has fewer than (-codePointOffset) code points.
2177
   * @since 1.5
2178
   */
2179
  public int offsetByCodePoints(int index, int codePointOffset)
2180
  {
2181
    if (index < 0 || index > count)
2182
      throw new IndexOutOfBoundsException();
2183
 
2184
    return Character.offsetByCodePoints(value, offset, count, offset + index,
2185
                                        codePointOffset);
2186
  }
2187
 
2188
  /**
2189
   * Returns true if, and only if, {@link #length()}
2190
   * is <code>0</code>.
2191
   *
2192
   * @return true if the length of the string is zero.
2193
   * @since 1.6
2194
   */
2195
  public boolean isEmpty()
2196
  {
2197
    return count == 0;
2198
  }
2199
 
2200
}

powered by: WebSVN 2.1.0

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