Source code: java/lang/String.java
1 /* String.java -- immutable character sequences; the object of string literals
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 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
44 import java.io.Serializable;
45 import java.io.UnsupportedEncodingException;
46 import java.nio.ByteBuffer;
47 import java.nio.CharBuffer;
48 import java.nio.charset.CharacterCodingException;
49 import java.nio.charset.Charset;
50 import java.nio.charset.CharsetDecoder;
51 import java.nio.charset.CharsetEncoder;
52 import java.nio.charset.CodingErrorAction;
53 import java.nio.charset.IllegalCharsetNameException;
54 import java.nio.charset.UnsupportedCharsetException;
55 import java.text.Collator;
56 import java.util.Comparator;
57 import java.util.Locale;
58 import java.util.regex.Matcher;
59 import java.util.regex.Pattern;
60 import java.util.regex.PatternSyntaxException;
61
62 /**
63 * Strings represent an immutable set of characters. All String literals
64 * are instances of this class, and two string literals with the same contents
65 * refer to the same String object.
66 *
67 * <p>This class also includes a number of methods for manipulating the
68 * contents of strings (of course, creating a new object if there are any
69 * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
70 * standards, where some character sequences have a different number of
71 * characters in the uppercase version than the lower case.
72 *
73 * <p>Strings are special, in that they are the only object with an overloaded
74 * operator. When you use '+' with at least one String argument, both
75 * arguments have String conversion performed on them, and another String (not
76 * guaranteed to be unique) results.
77 *
78 * <p>String is special-cased when doing data serialization - rather than
79 * listing the fields of this class, a String object is converted to a string
80 * literal in the object stream.
81 *
82 * @author Paul N. Fisher
83 * @author Eric Blake (ebb9@email.byu.edu)
84 * @author Per Bothner (bothner@cygnus.com)
85 * @since 1.0
86 * @status updated to 1.4; but could use better data sharing via offset field
87 */
88 public final class String implements Serializable, Comparable, CharSequence
89 {
90 // WARNING: String is a CORE class in the bootstrap cycle. See the comments
91 // in vm/reference/java/lang/Runtime for implications of this fact.
92
93 /**
94 * This is probably not necessary because this class is special cased already
95 * but it will avoid showing up as a discrepancy when comparing SUIDs.
96 */
97 private static final long serialVersionUID = -6849794470754667710L;
98
99 /**
100 * Stores unicode multi-character uppercase expansion table.
101 * @see #toUpperCase(char)
102 * @see CharData#UPPER_EXPAND
103 */
104 private static final char[] upperExpand
105 = zeroBasedStringValue(CharData.UPPER_EXPAND);
106
107 /**
108 * Stores unicode multi-character uppercase special casing table.
109 * @see #upperCaseExpansion(char)
110 * @see CharData#UPPER_SPECIAL
111 */
112 private static final char[] upperSpecial
113 = zeroBasedStringValue(CharData.UPPER_SPECIAL);
114
115 /**
116 * Characters which make up the String.
117 * Package access is granted for use by StringBuffer.
118 */
119 final char[] value;
120
121 /**
122 * Holds the number of characters in value. This number is generally
123 * the same as value.length, but can be smaller because substrings and
124 * StringBuffers can share arrays. Package visible for use by trusted code.
125 */
126 final int count;
127
128 /**
129 * Caches the result of hashCode(). If this value is zero, the hashcode
130 * is considered uncached (even if 0 is the correct hash value).
131 */
132 private int cachedHashCode;
133
134 /**
135 * Holds the starting position for characters in value[]. Since
136 * substring()'s are common, the use of offset allows the operation
137 * to perform in O(1). Package access is granted for use by StringBuffer.
138 */
139 final int offset;
140
141 /**
142 * An implementation for {@link CASE_INSENSITIVE_ORDER}.
143 * This must be {@link Serializable}. The class name is dictated by
144 * compatibility with Sun's JDK.
145 */
146 private static final class CaseInsensitiveComparator
147 implements Comparator, Serializable
148 {
149 /**
150 * Compatible with JDK 1.2.
151 */
152 private static final long serialVersionUID = 8575799808933029326L;
153
154 /**
155 * The default private constructor generates unnecessary overhead.
156 */
157 CaseInsensitiveComparator() {}
158
159 /**
160 * Compares to Strings, using
161 * <code>String.compareToIgnoreCase(String)</code>.
162 *
163 * @param o1 the first string
164 * @param o2 the second string
165 * @return < 0, 0, or > 0 depending on the case-insensitive
166 * comparison of the two strings.
167 * @throws NullPointerException if either argument is null
168 * @throws ClassCastException if either argument is not a String
169 * @see #compareToIgnoreCase(String)
170 */
171 public int compare(Object o1, Object o2)
172 {
173 return ((String) o1).compareToIgnoreCase((String) o2);
174 }
175 } // class CaseInsensitiveComparator
176
177 /**
178 * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
179 * This comparator is {@link Serializable}. Note that it ignores Locale,
180 * for that, you want a Collator.
181 *
182 * @see Collator#compare(String, String)
183 * @since 1.2
184 */
185 public static final Comparator CASE_INSENSITIVE_ORDER
186 = new CaseInsensitiveComparator();
187
188 /**
189 * Creates an empty String (length 0). Unless you really need a new object,
190 * consider using <code>""</code> instead.
191 */
192 public String()
193 {
194 value = "".value;
195 offset = 0;
196 count = 0;
197 }
198
199 /**
200 * Copies the contents of a String to a new String. Since Strings are
201 * immutable, only a shallow copy is performed.
202 *
203 * @param str String to copy
204 * @throws NullPointerException if value is null
205 */
206 public String(String str)
207 {
208 value = str.value;
209 offset = str.offset;
210 count = str.count;
211 cachedHashCode = str.cachedHashCode;
212 }
213
214 /**
215 * Creates a new String using the character sequence of the char array.
216 * Subsequent changes to data do not affect the String.
217 *
218 * @param data char array to copy
219 * @throws NullPointerException if data is null
220 */
221 public String(char[] data)
222 {
223 this(data, 0, data.length, false);
224 }
225
226 /**
227 * Creates a new String using the character sequence of a subarray of
228 * characters. The string starts at offset, and copies count chars.
229 * Subsequent changes to data do not affect the String.
230 *
231 * @param data char array to copy
232 * @param offset position (base 0) to start copying out of data
233 * @param count the number of characters from data to copy
234 * @throws NullPointerException if data is null
235 * @throws IndexOutOfBoundsException if (offset < 0 || count < 0
236 * || offset + count > data.length)
237 * (while unspecified, this is a StringIndexOutOfBoundsException)
238 */
239 public String(char[] data, int offset, int count)
240 {
241 this(data, offset, count, false);
242 }
243
244 /**
245 * Creates a new String using an 8-bit array of integer values, starting at
246 * an offset, and copying up to the count. Each character c, using
247 * corresponding byte b, is created in the new String as if by performing:
248 *
249 * <pre>
250 * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff))
251 * </pre>
252 *
253 * @param ascii array of integer values
254 * @param hibyte top byte of each Unicode character
255 * @param offset position (base 0) to start copying out of ascii
256 * @param count the number of characters from ascii to copy
257 * @throws NullPointerException if ascii is null
258 * @throws IndexOutOfBoundsException if (offset < 0 || count < 0
259 * || offset + count > ascii.length)
260 * (while unspecified, this is a StringIndexOutOfBoundsException)
261 * @see #String(byte[])
262 * @see #String(byte[], String)
263 * @see #String(byte[], int, int)
264 * @see #String(byte[], int, int, String)
265 * @deprecated use {@link #String(byte[], int, int, String)} to perform
266 * correct encoding
267 */
268 public String(byte[] ascii, int hibyte, int offset, int count)
269 {
270 if (offset < 0 || count < 0 || offset + count > ascii.length)
271 throw new StringIndexOutOfBoundsException();
272 value = new char[count];
273 this.offset = 0;
274 this.count = count;
275 hibyte <<= 8;
276 offset += count;
277 while (--count >= 0)
278 value[count] = (char) (hibyte | (ascii[--offset] & 0xff));
279 }
280
281 /**
282 * Creates a new String using an 8-bit array of integer values. Each
283 * character c, using corresponding byte b, is created in the new String
284 * as if by performing:
285 *
286 * <pre>
287 * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff))
288 * </pre>
289 *
290 * @param ascii array of integer values
291 * @param hibyte top byte of each Unicode character
292 * @throws NullPointerException if ascii is null
293 * @see #String(byte[])
294 * @see #String(byte[], String)
295 * @see #String(byte[], int, int)
296 * @see #String(byte[], int, int, String)
297 * @see #String(byte[], int, int, int)
298 * @deprecated use {@link #String(byte[], String)} to perform
299 * correct encoding
300 */
301 public String(byte[] ascii, int hibyte)
302 {
303 this(ascii, hibyte, 0, ascii.length);
304 }
305
306 /**
307 * Creates a new String using the portion of the byte array starting at the
308 * offset and ending at offset + count. Uses the specified encoding type
309 * to decode the byte array, so the resulting string may be longer or
310 * shorter than the byte array. For more decoding control, use
311 * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
312 * see {@link java.nio.charset.Charset}. The behavior is not specified if
313 * the decoder encounters invalid characters; this implementation throws
314 * an Error.
315 *
316 * @param data byte array to copy
317 * @param offset the offset to start at
318 * @param count the number of bytes in the array to use
319 * @param encoding the name of the encoding to use
320 * @throws NullPointerException if data or encoding is null
321 * @throws IndexOutOfBoundsException if offset or count is incorrect
322 * (while unspecified, this is a StringIndexOutOfBoundsException)
323 * @throws UnsupportedEncodingException if encoding is not found
324 * @throws Error if the decoding fails
325 * @since 1.1
326 */
327 public String(byte[] data, int offset, int count, String encoding)
328 throws UnsupportedEncodingException
329 {
330 if (offset < 0 || count < 0 || offset + count > data.length)
331 throw new StringIndexOutOfBoundsException();
332 try
333 {
334 CharsetDecoder csd = Charset.forName(encoding).newDecoder();
335 csd.onMalformedInput(CodingErrorAction.REPLACE);
336 csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
337 CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
338 if(cbuf.hasArray())
339 {
340 value = cbuf.array();
341 this.offset = cbuf.position();
342 this.count = cbuf.remaining();
343 } else {
344 // Doubt this will happen. But just in case.
345 value = new char[cbuf.remaining()];
346 cbuf.get(value);
347 this.offset = 0;
348 this.count = value.length;
349 }
350 } catch(CharacterCodingException e){
351 throw new UnsupportedEncodingException("Encoding: "+encoding+
352 " not found.");
353 } catch(IllegalCharsetNameException e){
354 throw new UnsupportedEncodingException("Encoding: "+encoding+
355 " not found.");
356 } catch(UnsupportedCharsetException e){
357 throw new UnsupportedEncodingException("Encoding: "+encoding+
358 " not found.");
359 }
360 }
361
362 /**
363 * Creates a new String using the byte array. Uses the specified encoding
364 * type to decode the byte array, so the resulting string may be longer or
365 * shorter than the byte array. For more decoding control, use
366 * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
367 * see {@link java.nio.charset.Charset}. The behavior is not specified if
368 * the decoder encounters invalid characters; this implementation throws
369 * an Error.
370 *
371 * @param data byte array to copy
372 * @param encoding the name of the encoding to use
373 * @throws NullPointerException if data or encoding is null
374 * @throws UnsupportedEncodingException if encoding is not found
375 * @throws Error if the decoding fails
376 * @see #String(byte[], int, int, String)
377 * @since 1.1
378 */
379 public String(byte[] data, String encoding)
380 throws UnsupportedEncodingException
381 {
382 this(data, 0, data.length, encoding);
383 }
384
385 /**
386 * Creates a new String using the portion of the byte array starting at the
387 * offset and ending at offset + count. Uses the encoding of the platform's
388 * default charset, so the resulting string may be longer or shorter than
389 * the byte array. For more decoding control, use
390 * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
391 * if the decoder encounters invalid characters; this implementation throws
392 * an Error.
393 *
394 * @param data byte array to copy
395 * @param offset the offset to start at
396 * @param count the number of bytes in the array to use
397 * @throws NullPointerException if data is null
398 * @throws IndexOutOfBoundsException if offset or count is incorrect
399 * @throws Error if the decoding fails
400 * @see #String(byte[], int, int, String)
401 * @since 1.1
402 */
403 public String(byte[] data, int offset, int count)
404 {
405 if (offset < 0 || count < 0 || offset + count > data.length)
406 throw new StringIndexOutOfBoundsException();
407 int o, c;
408 char[] v;
409 String encoding;
410 try
411 {
412 encoding = System.getProperty("file.encoding");
413 CharsetDecoder csd = Charset.forName(encoding).newDecoder();
414 csd.onMalformedInput(CodingErrorAction.REPLACE);
415 csd.onUnmappableCharacter(CodingErrorAction.REPLACE);
416 CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count));
417 if(cbuf.hasArray())
418 {
419 v = cbuf.array();
420 o = cbuf.position();
421 c = cbuf.remaining();
422 } else {
423 // Doubt this will happen. But just in case.
424 v = new char[cbuf.remaining()];
425 cbuf.get(v);
426 o = 0;
427 c = v.length;
428 }
429 } catch(Exception ex){
430 // If anything goes wrong (System property not set,
431 // NIO provider not available, etc)
432 // Default to the 'safe' encoding ISO8859_1
433 v = new char[count];
434 o = 0;
435 c = count;
436 for (int i=0;i<count;i++)
437 v[i] = (char)data[offset+i];
438 }
439 this.value = v;
440 this.offset = o;
441 this.count = c;
442 }
443
444 /**
445 * Creates a new String using the byte array. Uses the encoding of the
446 * platform's default charset, so the resulting string may be longer or
447 * shorter than the byte array. For more decoding control, use
448 * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
449 * if the decoder encounters invalid characters; this implementation throws
450 * an Error.
451 *
452 * @param data byte array to copy
453 * @throws NullPointerException if data is null
454 * @throws Error if the decoding fails
455 * @see #String(byte[], int, int)
456 * @see #String(byte[], int, int, String)
457 * @since 1.1
458 */
459 public String(byte[] data)
460 {
461 this(data, 0, data.length);
462 }
463
464 /**
465 * Creates a new String using the character sequence represented by
466 * the StringBuffer. Subsequent changes to buf do not affect the String.
467 *
468 * @param buffer StringBuffer to copy
469 * @throws NullPointerException if buffer is null
470 */
471 public String(StringBuffer buffer)
472 {
473 synchronized (buffer)
474 {
475 offset = 0;
476 count = buffer.count;
477 // Share unless buffer is 3/4 empty.
478 if ((count << 2) < buffer.value.length)
479 {
480 value = new char[count];
481 VMSystem.arraycopy(buffer.value, 0, value, 0, count);
482 }
483 else
484 {
485 buffer.shared = true;
486 value = buffer.value;
487 }
488 }
489 }
490
491 /**
492 * Creates a new String using the character sequence represented by
493 * the StringBuilder. Subsequent changes to buf do not affect the String.
494 *
495 * @param buffer StringBuilder to copy
496 * @throws NullPointerException if buffer is null
497 */
498 public String(StringBuilder buffer)
499 {
500 this(buffer.value, 0, buffer.count);
501 }
502
503 /**
504 * Special constructor which can share an array when safe to do so.
505 *
506 * @param data the characters to copy
507 * @param offset the location to start from
508 * @param count the number of characters to use
509 * @param dont_copy true if the array is trusted, and need not be copied
510 * @throws NullPointerException if chars is null
511 * @throws StringIndexOutOfBoundsException if bounds check fails
512 */
513 String(char[] data, int offset, int count, boolean dont_copy)
514 {
515 if (offset < 0 || count < 0 || offset + count > data.length)
516 throw new StringIndexOutOfBoundsException();
517 if (dont_copy)
518 {
519 value = data;
520 this.offset = offset;
521 }
522 else
523 {
524 value = new char[count];
525 VMSystem.arraycopy(data, offset, value, 0, count);
526 this.offset = 0;
527 }
528 this.count = count;
529 }
530
531 /**
532 * Returns the number of characters contained in this String.
533 *
534 * @return the length of this String
535 */
536 public int length()
537 {
538 return count;
539 }
540
541 /**
542 * Returns the character located at the specified index within this String.
543 *
544 * @param index position of character to return (base 0)
545 * @return character located at position index
546 * @throws IndexOutOfBoundsException if index < 0 || index >= length()
547 * (while unspecified, this is a StringIndexOutOfBoundsException)
548 */
549 public char charAt(int index)
550 {
551 if (index < 0 || index >= count)
552 throw new StringIndexOutOfBoundsException(index);
553 return value[offset + index];
554 }
555
556 /**
557 * Copies characters from this String starting at a specified start index,
558 * ending at a specified stop index, to a character array starting at
559 * a specified destination begin index.
560 *
561 * @param srcBegin index to begin copying characters from this String
562 * @param srcEnd index after the last character to be copied from this String
563 * @param dst character array which this String is copied into
564 * @param dstBegin index to start writing characters into dst
565 * @throws NullPointerException if dst is null
566 * @throws IndexOutOfBoundsException if any indices are out of bounds
567 * (while unspecified, source problems cause a
568 * StringIndexOutOfBoundsException, and dst problems cause an
569 * ArrayIndexOutOfBoundsException)
570 */
571 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
572 {
573 if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
574 throw new StringIndexOutOfBoundsException();
575 VMSystem.arraycopy(value, srcBegin + offset,
576 dst, dstBegin, srcEnd - srcBegin);
577 }
578
579 /**
580 * Copies the low byte of each character from this String starting at a
581 * specified start index, ending at a specified stop index, to a byte array
582 * starting at a specified destination begin index.
583 *
584 * @param srcBegin index to being copying characters from this String
585 * @param srcEnd index after the last character to be copied from this String
586 * @param dst byte array which each low byte of this String is copied into
587 * @param dstBegin index to start writing characters into dst
588 * @throws NullPointerException if dst is null and copy length is non-zero
589 * @throws IndexOutOfBoundsException if any indices are out of bounds
590 * (while unspecified, source problems cause a
591 * StringIndexOutOfBoundsException, and dst problems cause an
592 * ArrayIndexOutOfBoundsException)
593 * @see #getBytes()
594 * @see #getBytes(String)
595 * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
596 */
597 public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)
598 {
599 if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
600 throw new StringIndexOutOfBoundsException();
601 int i = srcEnd - srcBegin;
602 srcBegin += offset;
603 while (--i >= 0)
604 dst[dstBegin++] = (byte) value[srcBegin++];
605 }
606
607 /**
608 * Converts the Unicode characters in this String to a byte array. Uses the
609 * specified encoding method, so the result may be longer or shorter than
610 * the String. For more encoding control, use
611 * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
612 * see {@link java.nio.charset.Charset}. Unsupported characters get
613 * replaced by an encoding specific byte.
614 *
615 * @param enc encoding name
616 * @return the resulting byte array
617 * @throws NullPointerException if enc is null
618 * @throws UnsupportedEncodingException if encoding is not supported
619 * @since 1.1
620 */
621 public byte[] getBytes(String enc) throws UnsupportedEncodingException
622 {
623 try
624 {
625 CharsetEncoder cse = Charset.forName(enc).newEncoder();
626 cse.onMalformedInput(CodingErrorAction.REPLACE);
627 cse.onUnmappableCharacter(CodingErrorAction.REPLACE);
628 ByteBuffer bbuf = cse.encode(CharBuffer.wrap(value, offset, count));
629 if(bbuf.hasArray())
630 return bbuf.array();
631
632 // Doubt this will happen. But just in case.
633 byte[] bytes = new byte[bbuf.remaining()];
634 bbuf.get(bytes);
635 return bytes;
636
637 } catch(IllegalCharsetNameException e){
638 throw new UnsupportedEncodingException("Encoding: "+enc+
639 " not found.");
640 } catch(UnsupportedCharsetException e){
641 throw new UnsupportedEncodingException("Encoding: "+enc+
642 " not found.");
643 } catch(CharacterCodingException e){
644 // XXX - Ignore coding exceptions? They shouldn't really happen.
645 return null;
646 }
647 }
648
649 /**
650 * Converts the Unicode characters in this String to a byte array. Uses the
651 * encoding of the platform's default charset, so the result may be longer
652 * or shorter than the String. For more encoding control, use
653 * {@link java.nio.charset.CharsetEncoder}. Unsupported characters get
654 * replaced by an encoding specific byte.
655 *
656 * @return the resulting byte array, or null on a problem
657 * @since 1.1
658 */
659 public byte[] getBytes()
660 {
661 try
662 {
663 return getBytes(System.getProperty("file.encoding"));
664 } catch(Exception e) {
665 // XXX - Throw an error here?
666 // For now, default to the 'safe' encoding.
667 byte[] bytes = new byte[count];
668 for(int i=0;i<count;i++)
669 bytes[i] = (byte)((value[offset+i] <= 0xFF)?
670 value[offset+i]:'?');
671 return bytes;
672 }
673 }
674
675 /**
676 * Predicate which compares anObject to this. This is true only for Strings
677 * with the same character sequence.
678 *
679 * @param anObject the object to compare
680 * @return true if anObject is semantically equal to this
681 * @see #compareTo(String)
682 * @see #equalsIgnoreCase(String)
683 */
684 public boolean equals(Object anObject)
685 {
686 if (! (anObject instanceof String))
687 return false;
688 String str2 = (String) anObject;
689 if (count != str2.count)
690 return false;
691 if (value == str2.value && offset == str2.offset)
692 return true;
693 int i = count;
694 int x = offset;
695 int y = str2.offset;
696 while (--i >= 0)
697 if (value[x++] != str2.value[y++])
698 return false;
699 return true;
700 }
701
702 /**
703 * Compares the given StringBuffer to this String. This is true if the
704 * StringBuffer has the same content as this String at this moment.
705 *
706 * @param buffer the StringBuffer to compare to
707 * @return true if StringBuffer has the same character sequence
708 * @throws NullPointerException if the given StringBuffer is null
709 * @since 1.4
710 */
711 public boolean contentEquals(StringBuffer buffer)
712 {
713 synchronized (buffer)
714 {
715 if (count != buffer.count)
716 return false;
717 if (value == buffer.value)
718 return true; // Possible if shared.
719 int i = count;
720 int x = offset + count;
721 while (--i >= 0)
722 if (value[--x] != buffer.value[i])
723 return false;
724 return true;
725 }
726 }
727
728 /**
729 * Compares a String to this String, ignoring case. This does not handle
730 * multi-character capitalization exceptions; instead the comparison is
731 * made on a character-by-character basis, and is true if:<br><ul>
732 * <li><code>c1 == c2</code></li>
733 * <li><code>Character.toUpperCase(c1)
734 * == Character.toUpperCase(c2)</code></li>
735 * <li><code>Character.toLowerCase(c1)
736 * == Character.toLowerCase(c2)</code></li>
737 * </ul>
738 *
739 * @param anotherString String to compare to this String
740 * @return true if anotherString is equal, ignoring case
741 * @see #equals(Object)
742 * @see Character#toUpperCase(char)
743 * @see Character#toLowerCase(char)
744 */
745 public boolean equalsIgnoreCase(String anotherString)
746 {
747 if (anotherString == null || count != anotherString.count)
748 return false;
749 int i = count;
750 int x = offset;
751 int y = anotherString.offset;
752 while (--i >= 0)
753 {
754 char c1 = value[x++];
755 char c2 = anotherString.value[y++];
756 // Note that checking c1 != c2 is redundant, but avoids method calls.
757 if (c1 != c2
758 && Character.toUpperCase(c1) != Character.toUpperCase(c2)
759 && Character.toLowerCase(c1) != Character.toLowerCase(c2))
760 return false;
761 }
762 return true;
763 }
764
765 /**
766 * Compares this String and another String (case sensitive,
767 * lexicographically). The result is less than 0 if this string sorts
768 * before the other, 0 if they are equal, and greater than 0 otherwise.
769 * After any common starting sequence is skipped, the result is
770 * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
771 * have characters remaining, or
772 * <code>this.length() - anotherString.length()</code> if one string is
773 * a subsequence of the other.
774 *
775 * @param anotherString the String to compare against
776 * @return the comparison
777 * @throws NullPointerException if anotherString is null
778 */
779 public int compareTo(String anotherString)
780 {
781 int i = Math.min(count, anotherString.count);
782 int x = offset;
783 int y = anotherString.offset;
784 while (--i >= 0)
785 {
786 int result = value[x++] - anotherString.value[y++];
787 if (result != 0)
788 return result;
789 }
790 return count - anotherString.count;
791 }
792
793 /**
794 * Behaves like <code>compareTo(java.lang.String)</code> unless the Object
795 * is not a <code>String</code>. Then it throws a
796 * <code>ClassCastException</code>.
797 *
798 * @param o the object to compare against
799 * @return the comparison
800 * @throws NullPointerException if o is null
801 * @throws ClassCastException if o is not a <code>String</code>
802 * @since 1.2
803 */
804 public int compareTo(Object o)
805 {
806 return compareTo((String) o);
807 }
808
809 /**
810 * Compares this String and another String (case insensitive). This
811 * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
812 * locale and multi-characater capitalization, and compares characters
813 * after performing
814 * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
815 * character of the string. This is unsatisfactory for locale-based
816 * comparison, in which case you should use {@link java.text.Collator}.
817 *
818 * @param str the string to compare against
819 * @return the comparison
820 * @see Collator#compare(String, String)
821 * @since 1.2
822 */
823 public int compareToIgnoreCase(String str)
824 {
825 int i = Math.min(count, str.count);
826 int x = offset;
827 int y = str.offset;
828 while (--i >= 0)
829 {
830 int result = Character.toLowerCase(Character.toUpperCase(value[x++]))
831 - Character.toLowerCase(Character.toUpperCase(str.value[y++]));
832 if (result != 0)
833 return result;
834 }
835 return count - str.count;
836 }
837
838 /**
839 * Predicate which determines if this String matches another String
840 * starting at a specified offset for each String and continuing
841 * for a specified length. Indices out of bounds are harmless, and give
842 * a false result.
843 *
844 * @param toffset index to start comparison at for this String
845 * @param other String to compare region to this String
846 * @param ooffset index to start comparison at for other
847 * @param len number of characters to compare
848 * @return true if regions match (case sensitive)
849 * @throws NullPointerException if other is null
850 */
851 public boolean regionMatches(int toffset, String other, int ooffset, int len)
852 {
853 return regionMatches(false, toffset, other, ooffset, len);
854 }
855
856 /**
857 * Predicate which determines if this String matches another String
858 * starting at a specified offset for each String and continuing
859 * for a specified length, optionally ignoring case. Indices out of bounds
860 * are harmless, and give a false result. Case comparisons are based on
861 * <code>Character.toLowerCase()</code> and
862 * <code>Character.toUpperCase()</code>, not on multi-character
863 * capitalization expansions.
864 *
865 * @param ignoreCase true if case should be ignored in comparision
866 * @param toffset index to start comparison at for this String
867 * @param other String to compare region to this String
868 * @param ooffset index to start comparison at for other
869 * @param len number of characters to compare
870 * @return true if regions match, false otherwise
871 * @throws NullPointerException if other is null
872 */
873 public boolean regionMatches(boolean ignoreCase, int toffset,
874 String other, int ooffset, int len)
875 {
876 if (toffset < 0 || ooffset < 0 || toffset + len > count
877 || ooffset + len > other.count)
878 return false;
879 toffset += offset;
880 ooffset += other.offset;
881 while (--len >= 0)
882 {
883 char c1 = value[toffset++];
884 char c2 = other.value[ooffset++];
885 // Note that checking c1 != c2 is redundant when ignoreCase is true,
886 // but it avoids method calls.
887 if (c1 != c2
888 && (! ignoreCase
889 || (Character.toLowerCase(c1) != Character.toLowerCase(c2)
890 && (Character.toUpperCase(c1)
891 != Character.toUpperCase(c2)))))
892 return false;
893 }
894 return true;
895 }
896
897 /**
898 * Predicate which determines if this String contains the given prefix,
899 * beginning comparison at toffset. The result is false if toffset is
900 * negative or greater than this.length(), otherwise it is the same as
901 * <code>this.substring(toffset).startsWith(prefix)</code>.
902 *
903 * @param prefix String to compare
904 * @param toffset offset for this String where comparison starts
905 * @return true if this String starts with prefix
906 * @throws NullPointerException if prefix is null
907 * @see #regionMatches(boolean, int, String, int, int)
908 */
909 public boolean startsWith(String prefix, int toffset)
910 {
911 return regionMatches(false, toffset, prefix, 0, prefix.count);
912 }
913
914 /**
915 * Predicate which determines if this String starts with a given prefix.
916 * If the prefix is an empty String, true is returned.
917 *
918 * @param prefix String to compare
919 * @return true if this String starts with the prefix
920 * @throws NullPointerException if prefix is null
921 * @see #startsWith(String, int)
922 */
923 public boolean startsWith(String prefix)
924 {
925 return regionMatches(false, 0, prefix, 0, prefix.count);
926 }
927
928 /**
929 * Predicate which determines if this String ends with a given suffix.
930 * If the suffix is an empty String, true is returned.
931 *
932 * @param suffix String to compare
933 * @return true if this String ends with the suffix
934 * @throws NullPointerException if suffix is null
935 * @see #regionMatches(boolean, int, String, int, int)
936 */
937 public boolean endsWith(String suffix)
938 {
939 return regionMatches(false, count - suffix.count, suffix, 0, suffix.count);
940 }
941
942 /**
943 * Computes the hashcode for this String. This is done with int arithmetic,
944 * where ** represents exponentiation, by this formula:<br>
945 * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
946 *
947 * @return hashcode value of this String
948 */
949 public int hashCode()
950 {
951 if (cachedHashCode != 0)
952 return cachedHashCode;
953
954 // Compute the hash code using a local variable to be reentrant.
955 int hashCode = 0;
956 int limit = count + offset;
957 for (int i = offset; i < limit; i++)
958 hashCode = hashCode * 31 + value[i];
959 return cachedHashCode = hashCode;
960 }
961
962 /**
963 * Finds the first instance of a character in this String.
964 *
965 * @param ch character to find
966 * @return location (base 0) of the character, or -1 if not found
967 */
968 public int indexOf(int ch)
969 {
970 return indexOf(ch, 0);
971 }
972
973 /**
974 * Finds the first instance of a character in this String, starting at
975 * a given index. If starting index is less than 0, the search
976 * starts at the beginning of this String. If the starting index
977 * is greater than the length of this String, -1 is returned.
978 *
979 * @param ch character to find
980 * @param fromIndex index to start the search
981 * @return location (base 0) of the character, or -1 if not found
982 */
983 public int indexOf(int ch, int fromIndex)
984 {
985 if ((char) ch != ch)
986 return -1;
987 if (fromIndex < 0)
988 fromIndex = 0;
989 int i = fromIndex + offset;
990 for ( ; fromIndex < count; fromIndex++)
991 if (value[i++] == ch)
992 return fromIndex;
993 return -1;
994 }
995
996 /**
997 * Finds the last instance of a character in this String.
998 *
999 * @param ch character to find
1000 * @return location (base 0) of the character, or -1 if not found
1001 */
1002 public int lastIndexOf(int ch)
1003 {
1004 return lastIndexOf(ch, count - 1);
1005 }
1006
1007 /**
1008 * Finds the last instance of a character in this String, starting at
1009 * a given index. If starting index is greater than the maximum valid
1010 * index, then the search begins at the end of this String. If the
1011 * starting index is less than zero, -1 is returned.
1012 *
1013 * @param ch character to find
1014 * @param fromIndex index to start the search
1015 * @return location (base 0) of the character, or -1 if not found
1016 */
1017 public int lastIndexOf(int ch, int fromIndex)
1018 {
1019 if ((char) ch != ch)
1020 return -1;
1021 if (fromIndex >= count)
1022 fromIndex = count - 1;
1023 int i = fromIndex + offset;
1024 for ( ; fromIndex >= 0; fromIndex--)
1025 if (value[i--] == ch)
1026 return fromIndex;
1027 return -1;
1028 }
1029
1030 /**
1031 * Finds the first instance of a String in this String.
1032 *
1033 * @param str String to find
1034 * @return location (base 0) of the String, or -1 if not found
1035 * @throws NullPointerException if str is null
1036 */
1037 public int indexOf(String str)
1038 {
1039 return indexOf(str, 0);
1040 }
1041
1042 /**
1043 * Finds the first instance of a String in this String, starting at
1044 * a given index. If starting index is less than 0, the search
1045 * starts at the beginning of this String. If the starting index
1046 * is greater than the length of this String, -1 is returned.
1047 *
1048 * @param str String to find
1049 * @param fromIndex index to start the search
1050 * @return location (base 0) of the String, or -1 if not found
1051 * @throws NullPointerException if str is null
1052 */
1053 public int indexOf(String str, int fromIndex)
1054 {
1055 if (fromIndex < 0)
1056 fromIndex = 0;
1057 int limit = count - str.count;
1058 for ( ; fromIndex <= limit; fromIndex++)
1059 if (regionMatches(fromIndex, str, 0, str.count))
1060 return fromIndex;
1061 return -1;
1062 }
1063
1064 /**
1065 * Finds the last instance of a String in this String.
1066 *
1067 * @param str String to find
1068 * @return location (base 0) of the String, or -1 if not found
1069 * @throws NullPointerException if str is null
1070 */
1071 public int lastIndexOf(String str)
1072 {
1073 return lastIndexOf(str, count - str.count);
1074 }
1075
1076 /**
1077 * Finds the last instance of a String in this String, starting at
1078 * a given index. If starting index is greater than the maximum valid
1079 * index, then the search begins at the end of this String. If the
1080 * starting index is less than zero, -1 is returned.
1081 *
1082 * @param str String to find
1083 * @param fromIndex index to start the search
1084 * @return location (base 0) of the String, or -1 if not found
1085 * @throws NullPointerException if str is null
1086 */
1087 public int lastIndexOf(String str, int fromIndex)
1088 {
1089 fromIndex = Math.min(fromIndex, count - str.count);
1090 for ( ; fromIndex >= 0; fromIndex--)
1091 if (regionMatches(fromIndex, str, 0, str.count))
1092 return fromIndex;
1093 return -1;
1094 }
1095
1096 /**
1097 * Creates a substring of this String, starting at a specified index
1098 * and ending at the end of this String.
1099 *
1100 * @param begin index to start substring (base 0)
1101 * @return new String which is a substring of this String
1102 * @throws IndexOutOfBoundsException if begin < 0 || begin > length()
1103 * (while unspecified, this is a StringIndexOutOfBoundsException)
1104 */
1105 public String substring(int begin)
1106 {
1107 return substring(begin, count);
1108 }
1109
1110 /**
1111 * Creates a substring of this String, starting at a specified index
1112 * and ending at one character before a specified index.
1113 *
1114 * @param beginIndex index to start substring (inclusive, base 0)
1115 * @param endIndex index to end at (exclusive)
1116 * @return new String which is a substring of this String
1117 * @throws IndexOutOfBoundsException if begin < 0 || end > length()
1118 * || begin > end (while unspecified, this is a
1119 * StringIndexOutOfBoundsException)
1120 */
1121 public String substring(int beginIndex, int endIndex)
1122 {
1123 if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
1124 throw new StringIndexOutOfBoundsException();
1125 if (beginIndex == 0 && endIndex == count)
1126 return this;
1127 int len = endIndex - beginIndex;
1128 // Package constructor avoids an array copy.
1129 return new String(value, beginIndex + offset, len,
1130 (len << 2) >= value.length);
1131 }
1132
1133 /**
1134 * Creates a substring of this String, starting at a specified index
1135 * and ending at one character before a specified index. This behaves like
1136 * <code>substring(begin, end)</code>.
1137 *
1138 * @param begin index to start substring (inclusive, base 0)
1139 * @param end index to end at (exclusive)
1140 * @return new String which is a substring of this String
1141 * @throws IndexOutOfBoundsException if begin < 0 || end > length()
1142 * || begin > end
1143 * @since 1.4
1144 */
1145 public CharSequence subSequence(int begin, int end)
1146 {
1147 return substring(begin, end);
1148 }
1149
1150 /**
1151 * Concatenates a String to this String. This results in a new string unless
1152 * one of the two originals is "".
1153 *
1154 * @param str String to append to this String
1155 * @return newly concatenated String
1156 * @throws NullPointerException if str is null
1157 */
1158 public String concat(String str)
1159 {
1160 if (str.count == 0)
1161 return this;
1162 if (count == 0)
1163 return str;
1164 char[] newStr = new char[count + str.count];
1165 VMSystem.arraycopy(value, offset, newStr, 0, count);
1166 VMSystem.arraycopy(str.value, str.offset, newStr, count, str.count);
1167 // Package constructor avoids an array copy.
1168 return new String(newStr, 0, newStr.length, true);
1169 }
1170
1171 /**
1172 * Replaces every instance of a character in this String with a new
1173 * character. If no replacements occur, this is returned.
1174 *
1175 * @param oldChar the old character to replace
1176 * @param newChar the new character
1177 * @return new String with all instances of oldChar replaced with newChar
1178 */
1179 public String replace(char oldChar, char newChar)
1180 {
1181 if (oldChar == newChar)
1182 return this;
1183 int i = count;
1184 int x = offset - 1;
1185 while (--i >= 0)
1186 if (value[++x] == oldChar)
1187 break;
1188 if (i < 0)
1189 return this;
1190 char[] newStr = (char[]) value.clone();
1191 newStr[x] = newChar;
1192 while (--i >= 0)
1193 if (value[++x] == oldChar)
1194 newStr[x] = newChar;
1195 // Package constructor avoids an array copy.
1196 return new String(newStr, offset, count, true);
1197 }
1198
1199 /**
1200 * Test if this String matches a regular expression. This is shorthand for
1201 * <code>{@link Pattern}.matches(regex, this)</code>.
1202 *
1203 * @param regex the pattern to match
1204 * @return true if the pattern matches
1205 * @throws NullPointerException if regex is null
1206 * @throws PatternSyntaxException if regex is invalid
1207 * @see Pattern#matches(String, CharSequence)
1208 * @since 1.4
1209 */
1210 public boolean matches(String regex)
1211 {
1212 return Pattern.matches(regex, this);
1213 }
1214
1215 /**
1216 * Replaces the first substring match of the regular expression with a
1217 * given replacement. This is shorthand for <code>{@link Pattern}
1218 * .compile(regex).matcher(this).replaceFirst(replacement)</code>.
1219 *
1220 * @param regex the pattern to match
1221 * @param replacement the replacement string
1222 * @return the modified string
1223 * @throws NullPointerException if regex or replacement is null
1224 * @throws PatternSyntaxException if regex is invalid
1225 * @see #replaceAll(String, String)
1226 * @see Pattern#compile(String)
1227 * @see Pattern#matcher(CharSequence)
1228 * @see Matcher#replaceFirst(String)
1229 * @since 1.4
1230 */
1231 public String replaceFirst(String regex, String replacement)
1232 {
1233 return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
1234 }
1235
1236 /**
1237 * Replaces all matching substrings of the regular expression with a
1238 * given replacement. This is shorthand for <code>{@link Pattern}
1239 * .compile(regex).matcher(this).replaceAll(replacement)</code>.
1240 *
1241 * @param regex the pattern to match
1242 * @param replacement the replacement string
1243 * @return the modified string
1244 * @throws NullPointerException if regex or replacement is null
1245 * @throws PatternSyntaxException if regex is invalid
1246 * @see #replaceFirst(String, String)
1247 * @see Pattern#compile(String)
1248 * @see Pattern#matcher(CharSequence)
1249 * @see Matcher#replaceAll(String)
1250 * @since 1.4
1251 */
1252 public String replaceAll(String regex, String replacement)
1253 {
1254 return Pattern.compile(regex).matcher(this).replaceAll(replacement);
1255 }
1256
1257 /**
1258 * Split this string around the matches of a regular expression. Each
1259 * element of the returned array is the largest block of characters not
1260 * terminated by the regular expression, in the order the matches are found.
1261 *
1262 * <p>The limit affects the length of the array. If it is positive, the
1263 * array will contain at most n elements (n - 1 pattern matches). If
1264 * negative, the array length is unlimited, but there can be trailing empty
1265 * entries. if 0, the array length is unlimited, and trailing empty entries
1266 * are discarded.
1267 *
1268 * <p>For example, splitting "boo:and:foo" yields:<br>
1269 * <table border=0>
1270 * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
1271 * <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr>
1272 * <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr>
1273 * <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
1274 * <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
1275 * <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
1276 * <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr>
1277 * </table>
1278 *
1279 * <p>This is shorthand for
1280 * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
1281 *
1282 * @param regex the pattern to match
1283 * @param limit the limit threshold
1284 * @return the array of split strings
1285 * @throws NullPointerException if regex or replacement is null
1286 * @throws PatternSyntaxException if regex is invalid
1287 * @see Pattern#compile(String)
1288 * @see Pattern#split(CharSequence, int)
1289 * @since 1.4
1290 */
1291 public String[] split(String regex, int limit)
1292 {
1293 return Pattern.compile(regex).split(this, limit);
1294 }
1295
1296 /**
1297 * Split this string around the matches of a regular expression. Each
1298 * element of the returned array is the largest block of characters not
1299 * terminated by the regular expression, in the order the matches are found.
1300 * The array length is unlimited, and trailing empty entries are discarded,
1301 * as though calling <code>split(regex, 0)</code>.
1302 *
1303 * @param regex the pattern to match
1304 * @return the array of split strings
1305 * @throws NullPointerException if regex or replacement is null
1306 * @throws PatternSyntaxException if regex is invalid
1307 * @see #split(String, int)
1308 * @see Pattern#compile(String)
1309 * @see Pattern#split(CharSequence, int)
1310 * @since 1.4
1311 */
1312 public String[] split(String regex)
1313 {
1314 return Pattern.compile(regex).split(this, 0);
1315 }
1316
1317 /**
1318 * Lowercases this String according to a particular locale. This uses
1319 * Unicode's special case mappings, as applied to the given Locale, so the
1320 * resulting string may be a different length.
1321 *
1322 * @param loc locale to use
1323 * @return new lowercased String, or this if no characters were lowercased
1324 * @throws NullPointerException if loc is null
1325 * @see #toUpperCase(Locale)
1326 * @since 1.1
1327 */
1328 public String toLowerCase(Locale loc)
1329 {
1330 // First, see if the current string is already lower case.
1331 boolean turkish = "tr".equals(loc.getLanguage());
1332 int i = count;
1333 int x = offset - 1;
1334 while (--i >= 0)
1335 {
1336 char ch = value[++x];
1337 if ((turkish && ch == '\u0049')
1338 || ch != Character.toLowerCase(ch))
1339 break;
1340 }
1341 if (i < 0)
1342 return this;
1343
1344 // Now we perform the conversion. Fortunately, there are no multi-character
1345 // lowercase expansions in Unicode 3.0.0.
1346 char[] newStr = (char[]) value.clone();
1347 do
1348 {
1349 char ch = value[x];
1350 // Hardcoded special case.
1351 newStr[x++] = (turkish && ch == '\u0049') ? '\u0131'
1352 : Character.toLowerCase(ch);
1353 }
1354 while (--i >= 0);
1355 // Package constructor avoids an array copy.
1356 return new String(newStr, offset, count, true);
1357 }
1358
1359 /**
1360 * Lowercases this String. This uses Unicode's special case mappings, as
1361 * applied to the platform's default Locale, so the resulting string may
1362 * be a different length.
1363 *
1364 * @return new lowercased String, or this if no characters were lowercased
1365 * @see #toLowerCase(Locale)
1366 * @see #toUpperCase()
1367 */
1368 public String toLowerCase()
1369 {
1370 return toLowerCase(Locale.getDefault());
1371 }
1372
1373 /**
1374 * Uppercases this String according to a particular locale. This uses
1375 * Unicode's special case mappings, as applied to the given Locale, so the
1376 * resulting string may be a different length.
1377 *
1378 * @param loc locale to use
1379 * @return new uppercased String, or this if no characters were uppercased
1380 * @throws NullPointerException if loc is null
1381 * @see #toLowerCase(Locale)
1382 * @since 1.1
1383 */
1384 public String toUpperCase(Locale loc)
1385 {
1386 // First, see how many characters we have to grow by, as well as if the
1387 // current string is already upper case.
1388 boolean turkish = "tr".equals(loc.getLanguage());
1389 int expand = 0;
1390 boolean unchanged = true;
1391 int i = count;
1392 int x = i + offset;
1393 while (--i >= 0)
1394 {
1395 char ch = value[--x];
1396 expand += upperCaseExpansion(ch);
1397 unchanged = (unchanged && expand == 0
1398 && ! (turkish && ch == '\u0069')
1399 && ch == Character.toUpperCase(ch));
1400 }
1401 if (unchanged)
1402 return this;
1403
1404 // Now we perform the conversion.
1405 i = count;
1406 if (expand == 0)
1407 {
1408 char[] newStr = (char[]) value.clone();
1409 while (--i >= 0)
1410 {
1411 char ch = value[x];
1412 // Hardcoded special case.
1413 newStr[x++] = (turkish && ch == '\u0069') ? '\u0130'
1414 : Character.toUpperCase(ch);
1415 }
1416 // Package constructor avoids an array copy.
1417 return new String(newStr, offset, count, true);
1418 }
1419
1420 // Expansion is necessary.
1421 char[] newStr = new char[count + expand];
1422 int j = 0;
1423 while (--i >= 0)
1424 {
1425 char ch = value[x++];
1426 // Hardcoded special case.
1427 if (turkish && ch == '\u0069')
1428 {
1429 newStr[j++] = '\u0130';
1430 continue;
1431 }
1432 expand = upperCaseExpansion(ch);
1433 if (expand > 0)
1434 {
1435 int index = upperCaseIndex(ch);
1436 while (expand-- >= 0)
1437 newStr[j++] = upperExpand[index++];
1438 }
1439 else
1440 newStr[j++] = Character.toUpperCase(ch);
1441 }
1442 // Package constructor avoids an array copy.
1443 return new String(newStr, 0, newStr.length, true);
1444 }
1445
1446 /**
1447 * Uppercases this String. This uses Unicode's special case mappings, as
1448 * applied to the platform's default Locale, so the resulting string may
1449 * be a different length.
1450 *
1451 * @return new uppercased String, or this if no characters were uppercased
1452 * @see #toUpperCase(Locale)
1453 * @see #toLowerCase()
1454 */
1455 public String toUpperCase()
1456 {
1457 return toUpperCase(Locale.getDefault());
1458 }
1459
1460 /**
1461 * Trims all characters less than or equal to <code>'\u0020'</code>
1462 * (<code>' '</code>) from the beginning and end of this String. This
1463 * includes many, but not all, ASCII control characters, and all
1464 * {@link Character#isWhitespace(char)}.
1465 *
1466 * @return new trimmed String, or this if nothing trimmed
1467 */
1468 public String trim()
1469 {
1470 int limit = count + offset;
1471 if (count == 0 || (value[offset] > '\u0020'
1472 && value[limit - 1] > '\u0020'))
1473 return this;
1474 int begin = offset;
1475 do
1476 if (begin == limit)
1477 return "";
1478 while (value[begin++] <= '\u0020');
1479 int end = limit;
1480 while (value[--end] <= '\u0020');
1481 return substring(begin - offset - 1, end - offset + 1);
1482 }
1483
1484 /**
1485 * Returns this, as it is already a String!
1486 *
1487 * @return this
1488 */
1489 public String toString()
1490 {
1491 return this;
1492 }
1493
1494 /**
1495 * Copies the contents of this String into a character array. Subsequent
1496 * changes to the array do not affect the String.
1497 *
1498 * @return character array copying the String
1499 */
1500 public char[] toCharArray()
1501 {
1502 if (count == value.length)
1503 return (char[]) value.clone();
1504
1505 char[] copy = new char