Showing the changes to java/pkg/java/lang/String.java (1 of 1 file). Show all
Unified · Split
| @@ -110,14 +110,22 @@ import java.util.regex.PatternSyntaxException; · 109 unmodified lines | ||
| 110 | 110 | public final class String |
| 111 | 111 | implements java.io.Serializable, Comparable<String>, CharSequence |
| 112 | 112 | { |
| 113 | + // [Inferno] < | |
| 114 | + | |
| 113 | 115 | /** The value is used for character storage. */ |
| 114 | − private final char value[]; | |
| 116 | + //private final char value[]; | |
| 115 | 117 | |
| 116 | 118 | /** The offset is the first index of the storage that is used. */ |
| 117 | − private final int offset; | |
| 119 | + //private final int offset; | |
| 118 | 120 | |
| 119 | 121 | /** The count is the number of characters in the String. */ |
| 120 | − private final int count; | |
| 122 | + //private final int count; | |
| 123 | + | |
| 124 | + /** The first field represents internal dis string. It is used by | |
| 125 | + Inferno's jvm to store and manipulate the actual string data. */ | |
| 126 | + private transient String disString; | |
| 127 | + | |
| 128 | + // [Inferno] > | |
| 121 | 129 | |
| 122 | 130 | /** Cache the hash code for the string */ |
| 123 | 131 | private int hash; // Default to 0 |
| @@ -145,11 +153,10 @@ public final class String · 21 unmodified lines | ||
| 145 | 153 | * an empty character sequence. Note that use of this constructor is |
| 146 | 154 | * unnecessary since Strings are immutable. |
| 147 | 155 | */ |
| 156 | + // [Inferno] < | |
| 148 | 157 | public String() { |
| 149 | − this.offset = 0; | |
| 150 | − this.count = 0; | |
| 151 | − this.value = new char[0]; | |
| 152 | 158 | } |
| 159 | + // [Inferno] > | |
| 153 | 160 | |
| 154 | 161 | /** |
| 155 | 162 | * Initializes a newly created {@code String} object so that it represents |
| @@ -162,23 +169,29 @@ public final class String · 6 unmodified lines | ||
| 162 | 169 | * A {@code String} |
| 163 | 170 | */ |
| 164 | 171 | public String(String original) { |
| 165 | − int size = original.count; | |
| 166 | − char[] originalValue = original.value; | |
| 167 | − char[] v; | |
| 168 | − if (originalValue.length > size) { | |
| 169 | − // The array representing the String is bigger than the new | |
| 170 | − // String itself. Perhaps this constructor is being called | |
| 171 | − // in order to trim the baggage, so make a copy of the array. | |
| 172 | − int off = original.offset; | |
| 173 | − v = Arrays.copyOfRange(originalValue, off, off+size); | |
| 174 | − } else { | |
| 175 | − // The array representing the String is the same | |
| 176 | − // size as the String, so no point in making a copy. | |
| 177 | − v = originalValue; | |
| 178 | − } | |
| 179 | − this.offset = 0; | |
| 180 | − this.count = size; | |
| 181 | − this.value = v; | |
| 172 | + //int size = original.count; | |
| 173 | + //char[] originalValue = original.value; | |
| 174 | + //char[] v; | |
| 175 | + //if (originalValue.length > size) { | |
| 176 | + // // The array representing the String is bigger than the new | |
| 177 | + // // String itself. Perhaps this constructor is being called | |
| 178 | + // // in order to trim the baggage, so make a copy of the array. | |
| 179 | + // int off = original.offset; | |
| 180 | + // v = Arrays.copyOfRange(originalValue, off, off+size); | |
| 181 | + //} else { | |
| 182 | + // // The array representing the String is the same | |
| 183 | + // // size as the String, so no point in making a copy. | |
| 184 | + // v = originalValue; | |
| 185 | + //} | |
| 186 | + //this.offset = 0; | |
| 187 | + //this.count = size; | |
| 188 | + //this.value = v; | |
| 189 | + if (original == null) | |
| 190 | + throw new NullPointerException(); | |
| 191 | + | |
| 192 | + // [Inferno] < | |
| 193 | + disString = original.disString; | |
| 194 | + // [Inferno] > | |
| 182 | 195 | } |
| 183 | 196 | |
| 184 | 197 | /** |
| @@ -191,10 +204,16 @@ public final class String · 6 unmodified lines | ||
| 191 | 204 | * The initial value of the string |
| 192 | 205 | */ |
| 193 | 206 | public String(char value[]) { |
| 194 | − int size = value.length; | |
| 195 | − this.offset = 0; | |
| 196 | − this.count = size; | |
| 197 | − this.value = Arrays.copyOf(value, size); | |
| 207 | + //int size = value.length; | |
| 208 | + //this.offset = 0; | |
| 209 | + //this.count = size; | |
| 210 | + //this.value = Arrays.copyOf(value, size); | |
| 211 | + if (value == null) | |
| 212 | + throw new NullPointerException(); | |
| 213 | + | |
| 214 | + // [Inferno] < | |
| 215 | + fill(value, 0, value.length); | |
| 216 | + // [Inferno] > | |
| 198 | 217 | } |
| 199 | 218 | |
| 200 | 219 | /** |
| @@ -229,9 +248,12 @@ public final class String · 28 unmodified lines | ||
| 229 | 248 | if (offset > value.length - count) { |
| 230 | 249 | throw new StringIndexOutOfBoundsException(offset + count); |
| 231 | 250 | } |
| 232 | − this.offset = 0; | |
| 233 | − this.count = count; | |
| 234 | − this.value = Arrays.copyOfRange(value, offset, offset+count); | |
| 251 | + //this.offset = 0; | |
| 252 | + //this.count = count; | |
| 253 | + | |
| 254 | + // [Inferno] < | |
| 255 | + fill(value, offset, count); | |
| 256 | + // [Inferno] > | |
| 235 | 257 | } |
| 236 | 258 | |
| 237 | 259 | /** |
| @@ -298,9 +320,13 @@ public final class String · 60 unmodified lines | ||
| 298 | 320 | Character.toSurrogates(c, v, j++); |
| 299 | 321 | } |
| 300 | 322 | |
| 301 | − this.value = v; | |
| 302 | − this.count = n; | |
| 303 | − this.offset = 0; | |
| 323 | + //this.value = v; | |
| 324 | + //this.count = n; | |
| 325 | + //this.offset = 0; | |
| 326 | + | |
| 327 | + // [Inferno] < | |
| 328 | + fill(v, 0, v.length); | |
| 329 | + // [Inferno] > | |
| 304 | 330 | } |
| 305 | 331 | |
| 306 | 332 | /** |
| @@ -357,9 +383,13 @@ public final class String · 50 unmodified lines | ||
| 357 | 383 | value[i] = (char) (hibyte | (ascii[i + offset] & 0xff)); |
| 358 | 384 | } |
| 359 | 385 | } |
| 360 | − this.offset = 0; | |
| 361 | − this.count = count; | |
| 362 | − this.value = value; | |
| 386 | + //this.offset = 0; | |
| 387 | + //this.count = count; | |
| 388 | + //this.value = value; | |
| 389 | + | |
| 390 | + // [Inferno] < | |
| 391 | + fill(value, 0, value.length); | |
| 392 | + // [Inferno] > | |
| 363 | 393 | } |
| 364 | 394 | |
| 365 | 395 | /** |
| @@ -429,7 +459,7 @@ public final class String · 63 unmodified lines | ||
| 429 | 459 | * |
| 430 | 460 | * @param length |
| 431 | 461 | * The number of bytes to decode |
| 432 | − | |
| 462 | + * | |
| 433 | 463 | * @param charsetName |
| 434 | 464 | * The name of a supported {@linkplain java.nio.charset.Charset |
| 435 | 465 | * charset} |
| @@ -450,9 +480,13 @@ public final class String · 14 unmodified lines | ||
| 450 | 480 | throw new NullPointerException("charsetName"); |
| 451 | 481 | checkBounds(bytes, offset, length); |
| 452 | 482 | char[] v = StringCoding.decode(charsetName, bytes, offset, length); |
| 453 | − this.offset = 0; | |
| 454 | − this.count = v.length; | |
| 455 | − this.value = v; | |
| 483 | + //this.offset = 0; | |
| 484 | + //this.count = v.length; | |
| 485 | + //this.value = v; | |
| 486 | + | |
| 487 | + // [Inferno] < | |
| 488 | + fill(v, 0, v.length); | |
| 489 | + // [Inferno] > | |
| 456 | 490 | } |
| 457 | 491 | |
| 458 | 492 | /** |
| @@ -490,9 +524,13 @@ public final class String · 31 unmodified lines | ||
| 490 | 524 | throw new NullPointerException("charset"); |
| 491 | 525 | checkBounds(bytes, offset, length); |
| 492 | 526 | char[] v = StringCoding.decode(charset, bytes, offset, length); |
| 493 | − this.offset = 0; | |
| 494 | − this.count = v.length; | |
| 495 | − this.value = v; | |
| 527 | + //this.offset = 0; | |
| 528 | + //this.count = v.length; | |
| 529 | + //this.value = v; | |
| 530 | + | |
| 531 | + // [Inferno] < | |
| 532 | + fill(v, 0, v.length); | |
| 533 | + // [Inferno] > | |
| 496 | 534 | } |
| 497 | 535 | |
| 498 | 536 | /** |
| @@ -577,9 +615,13 @@ public final class String · 78 unmodified lines | ||
| 577 | 615 | public String(byte bytes[], int offset, int length) { |
| 578 | 616 | checkBounds(bytes, offset, length); |
| 579 | 617 | char[] v = StringCoding.decode(bytes, offset, length); |
| 580 | − this.offset = 0; | |
| 581 | − this.count = v.length; | |
| 582 | − this.value = v; | |
| 618 | + //this.offset = 0; | |
| 619 | + //this.count = v.length; | |
| 620 | + //this.value = v; | |
| 621 | + | |
| 622 | + // [Inferno] < | |
| 623 | + fill(v, 0, v.length); | |
| 624 | + // [Inferno] > | |
| 583 | 625 | } |
| 584 | 626 | |
| 585 | 627 | /** |
| @@ -612,10 +654,9 @@ public final class String · 26 unmodified lines | ||
| 612 | 654 | * A {@code StringBuffer} |
| 613 | 655 | */ |
| 614 | 656 | public String(StringBuffer buffer) { |
| 615 | − String result = buffer.toString(); | |
| 616 | − this.value = result.value; | |
| 617 | − this.count = result.count; | |
| 618 | − this.offset = result.offset; | |
| 657 | + // [Inferno] < | |
| 658 | + this(buffer.toString()); | |
| 659 | + // [Inferno] > | |
| 619 | 660 | } |
| 620 | 661 | |
| 621 | 662 | /** |
| @@ -634,18 +675,19 @@ public final class String · 12 unmodified lines | ||
| 634 | 675 | * @since 1.5 |
| 635 | 676 | */ |
| 636 | 677 | public String(StringBuilder builder) { |
| 637 | − String result = builder.toString(); | |
| 638 | − this.value = result.value; | |
| 639 | − this.count = result.count; | |
| 640 | − this.offset = result.offset; | |
| 678 | + // [Inferno] < | |
| 679 | + this(builder.toString()); | |
| 680 | + // [Inferno] > | |
| 641 | 681 | } |
| 642 | 682 | |
| 643 | 683 | |
| 644 | 684 | // Package private constructor which shares value array for speed. |
| 645 | 685 | String(int offset, int count, char value[]) { |
| 646 | − this.value = value; | |
| 647 | − this.offset = offset; | |
| 648 | − this.count = count; | |
| 686 | + // TODO: implement real sharing | |
| 687 | + | |
| 688 | + // [Inferno] < | |
| 689 | + fill(value, offset, count); | |
| 690 | + // [Inferno] > | |
| 649 | 691 | } |
| 650 | 692 | |
| 651 | 693 | /** |
| @@ -656,9 +698,9 @@ public final class String · 4 unmodified lines | ||
| 656 | 698 | * @return the length of the sequence of characters represented by this |
| 657 | 699 | * object. |
| 658 | 700 | */ |
| 659 | − public int length() { | |
| 660 | − return count; | |
| 661 | − } | |
| 701 | + // [Inferno] < | |
| 702 | + public native int length(); | |
| 703 | + // [Inferno] > | |
| 662 | 704 | |
| 663 | 705 | /** |
| 664 | 706 | * Returns <tt>true</tt> if, and only if, {@link #length()} is <tt>0</tt>. |
| @@ -669,7 +711,9 @@ public final class String · 4 unmodified lines | ||
| 669 | 711 | * @since 1.6 |
| 670 | 712 | */ |
| 671 | 713 | public boolean isEmpty() { |
| 672 | − return count == 0; | |
| 714 | + // [Inferno] < | |
| 715 | + return length() == 0; | |
| 716 | + // [Inferno] > | |
| 673 | 717 | } |
| 674 | 718 | |
| 675 | 719 | /** |
| @@ -690,12 +734,9 @@ public final class String · 14 unmodified lines | ||
| 690 | 734 | * argument is negative or not less than the length of this |
| 691 | 735 | * string. |
| 692 | 736 | */ |
| 693 | − public char charAt(int index) { | |
| 694 | − if ((index < 0) || (index >= count)) { | |
| 695 | − throw new StringIndexOutOfBoundsException(index); | |
| 696 | − } | |
| 697 | − return value[index + offset]; | |
| 698 | − } | |
| 737 | + // [Inferno] < | |
| 738 | + public native char charAt(int index); | |
| 739 | + // [Inferno] > | |
| 699 | 740 | |
| 700 | 741 | /** |
| 701 | 742 | * Returns the character (Unicode code point) at the specified |
| @@ -720,10 +761,11 @@ public final class String · 18 unmodified lines | ||
| 720 | 761 | * @since 1.5 |
| 721 | 762 | */ |
| 722 | 763 | public int codePointAt(int index) { |
| 723 | − if ((index < 0) || (index >= count)) { | |
| 724 | − throw new StringIndexOutOfBoundsException(index); | |
| 725 | − } | |
| 726 | − return Character.codePointAtImpl(value, offset + index, offset + count); | |
| 764 | + //if ((index < 0) || (index >= count)) { | |
| 765 | + // throw new StringIndexOutOfBoundsException(index); | |
| 766 | + //} | |
| 767 | + //return Character.codePointAtImpl(value, offset + index, offset + count); | |
| 768 | + return 0; | |
| 727 | 769 | } |
| 728 | 770 | |
| 729 | 771 | /** |
| @@ -749,11 +791,12 @@ public final class String · 19 unmodified lines | ||
| 749 | 791 | * @since 1.5 |
| 750 | 792 | */ |
| 751 | 793 | public int codePointBefore(int index) { |
| 752 | − int i = index - 1; | |
| 753 | − if ((i < 0) || (i >= count)) { | |
| 754 | − throw new StringIndexOutOfBoundsException(index); | |
| 755 | − } | |
| 756 | − return Character.codePointBeforeImpl(value, offset + index, offset); | |
| 794 | + //int i = index - 1; | |
| 795 | + //if ((i < 0) || (i >= count)) { | |
| 796 | + // throw new StringIndexOutOfBoundsException(index); | |
| 797 | + //} | |
| 798 | + //return Character.codePointBeforeImpl(value, offset + index, offset); | |
| 799 | + return 0; | |
| 757 | 800 | } |
| 758 | 801 | |
| 759 | 802 | /** |
| @@ -778,10 +821,11 @@ public final class String · 18 unmodified lines | ||
| 778 | 821 | * @since 1.5 |
| 779 | 822 | */ |
| 780 | 823 | public int codePointCount(int beginIndex, int endIndex) { |
| 781 | − if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) { | |
| 782 | − throw new IndexOutOfBoundsException(); | |
| 783 | − } | |
| 784 | − return Character.codePointCountImpl(value, offset+beginIndex, endIndex-beginIndex); | |
| 824 | + //if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) { | |
| 825 | + // throw new IndexOutOfBoundsException(); | |
| 826 | + //} | |
| 827 | + //return Character.codePointCountImpl(value, offset+beginIndex, endIndex-beginIndex); | |
| 828 | + return 0; | |
| 785 | 829 | } |
| 786 | 830 | |
| 787 | 831 | /** |
| @@ -805,11 +849,12 @@ public final class String · 17 unmodified lines | ||
| 805 | 849 | * @since 1.5 |
| 806 | 850 | */ |
| 807 | 851 | public int offsetByCodePoints(int index, int codePointOffset) { |
| 808 | − if (index < 0 || index > count) { | |
| 809 | − throw new IndexOutOfBoundsException(); | |
| 810 | − } | |
| 811 | − return Character.offsetByCodePointsImpl(value, offset, count, | |
| 812 | − offset+index, codePointOffset) - offset; | |
| 852 | + //if (index < 0 || index > count) { | |
| 853 | + // throw new IndexOutOfBoundsException(); | |
| 854 | + //} | |
| 855 | + //return Character.offsetByCodePointsImpl(value, offset, count, | |
| 856 | + // offset+index, codePointOffset) - offset; | |
| 857 | + return 0; | |
| 813 | 858 | } |
| 814 | 859 | |
| 815 | 860 | /** |
| @@ -817,7 +862,9 @@ public final class String · 1 unmodified line | ||
| 817 | 862 | * This method doesn't perform any range checking. |
| 818 | 863 | */ |
| 819 | 864 | void getChars(char dst[], int dstBegin) { |
| 820 | − System.arraycopy(value, offset, dst, dstBegin, count); | |
| 865 | + // [Inferno] < | |
| 866 | + getChars(0, length(), dst, dstBegin); | |
| 867 | + // [Inferno] > | |
| 821 | 868 | } |
| 822 | 869 | |
| 823 | 870 | /** |
| @@ -850,19 +897,7 @@ public final class String · 26 unmodified lines | ||
| 850 | 897 | * <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than |
| 851 | 898 | * <code>dst.length</code></ul> |
| 852 | 899 | */ |
| 853 | − public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { | |
| 854 | − if (srcBegin < 0) { | |
| 855 | − throw new StringIndexOutOfBoundsException(srcBegin); | |
| 856 | − } | |
| 857 | − if (srcEnd > count) { | |
| 858 | − throw new StringIndexOutOfBoundsException(srcEnd); | |
| 859 | − } | |
| 860 | − if (srcBegin > srcEnd) { | |
| 861 | − throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); | |
| 862 | − } | |
| 863 | − System.arraycopy(value, offset + srcBegin, dst, dstBegin, | |
| 864 | − srcEnd - srcBegin); | |
| 865 | − } | |
| 900 | + public native void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin); | |
| 866 | 901 | |
| 867 | 902 | /** |
| 868 | 903 | * Copies characters from this string into the destination byte array. Each |
| @@ -912,16 +947,16 @@ public final class String · 43 unmodified lines | ||
| 912 | 947 | if (srcBegin < 0) { |
| 913 | 948 | throw new StringIndexOutOfBoundsException(srcBegin); |
| 914 | 949 | } |
| 915 | − if (srcEnd > count) { | |
| 950 | + if (srcEnd > length()) { | |
| 916 | 951 | throw new StringIndexOutOfBoundsException(srcEnd); |
| 917 | 952 | } |
| 918 | 953 | if (srcBegin > srcEnd) { |
| 919 | 954 | throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); |
| 920 | 955 | } |
| 921 | 956 | int j = dstBegin; |
| 922 | − int n = offset + srcEnd; | |
| 923 | − int i = offset + srcBegin; | |
| 924 | − char[] val = value; /* avoid getfield opcode */ | |
| 957 | + int n = srcEnd; | |
| 958 | + int i = srcBegin; | |
| 959 | + char[] val = toCharArray(); | |
| 925 | 960 | |
| 926 | 961 | while (i < n) { |
| 927 | 962 | dst[j++] = (byte)val[i++]; |
| @@ -952,7 +987,7 @@ public final class String · 24 unmodified lines | ||
| 952 | 987 | throws UnsupportedEncodingException |
| 953 | 988 | { |
| 954 | 989 | if (charsetName == null) throw new NullPointerException(); |
| 955 | − return StringCoding.encode(charsetName, value, offset, count); | |
| 990 | + return StringCoding.encode(charsetName, toCharArray(), 0, length()); | |
| 956 | 991 | } |
| 957 | 992 | |
| 958 | 993 | /** |
| @@ -975,7 +1010,7 @@ public final class String · 16 unmodified lines | ||
| 975 | 1010 | */ |
| 976 | 1011 | public byte[] getBytes(Charset charset) { |
| 977 | 1012 | if (charset == null) throw new NullPointerException(); |
| 978 | − return StringCoding.encode(charset, value, offset, count); | |
| 1013 | + return StringCoding.encode(charset, toCharArray(), 0, length()); | |
| 979 | 1014 | } |
| 980 | 1015 | |
| 981 | 1016 | /** |
| @@ -992,7 +1027,7 @@ public final class String · 10 unmodified lines | ||
| 992 | 1027 | * @since JDK1.1 |
| 993 | 1028 | */ |
| 994 | 1029 | public byte[] getBytes() { |
| 995 | − return StringCoding.encode(value, offset, count); | |
| 1030 | + return StringCoding.encode(toCharArray(), 0, length()); | |
| 996 | 1031 | } |
| 997 | 1032 | |
| 998 | 1033 | /** |
| @@ -1011,25 +1046,11 @@ public final class String · 12 unmodified lines | ||
| 1011 | 1046 | * @see #equalsIgnoreCase(String) |
| 1012 | 1047 | */ |
| 1013 | 1048 | public boolean equals(Object anObject) { |
| 1014 | − if (this == anObject) { | |
| 1015 | − return true; | |
| 1016 | − } | |
| 1017 | − if (anObject instanceof String) { | |
| 1018 | − String anotherString = (String)anObject; | |
| 1019 | − int n = count; | |
| 1020 | − if (n == anotherString.count) { | |
| 1021 | − char v1[] = value; | |
| 1022 | − char v2[] = anotherString.value; | |
| 1023 | − int i = offset; | |
| 1024 | − int j = anotherString.offset; | |
| 1025 | − while (n-- != 0) { | |
| 1026 | − if (v1[i++] != v2[j++]) | |
| 1027 | − return false; | |
| 1028 | − } | |
| 1029 | − return true; | |
| 1030 | − } | |
| 1031 | − } | |
| 1049 | + // [Inferno] < | |
| 1050 | + if (anObject instanceof String) | |
| 1051 | + return equality((String)anObject, false); | |
| 1032 | 1052 | return false; |
| 1053 | + // [Inferno] > | |
| 1033 | 1054 | } |
| 1034 | 1055 | |
| 1035 | 1056 | /** |
| @@ -1067,13 +1088,15 @@ public final class String · 31 unmodified lines | ||
| 1067 | 1088 | * @since 1.5 |
| 1068 | 1089 | */ |
| 1069 | 1090 | public boolean contentEquals(CharSequence cs) { |
| 1091 | + // [Inferno] < | |
| 1092 | + int count = length(); | |
| 1070 | 1093 | if (count != cs.length()) |
| 1071 | 1094 | return false; |
| 1072 | 1095 | // Argument is a StringBuffer, StringBuilder |
| 1073 | 1096 | if (cs instanceof AbstractStringBuilder) { |
| 1074 | − char v1[] = value; | |
| 1097 | + char v1[] = toCharArray(); | |
| 1075 | 1098 | char v2[] = ((AbstractStringBuilder)cs).getValue(); |
| 1076 | − int i = offset; | |
| 1099 | + int i = 0; | |
| 1077 | 1100 | int j = 0; |
| 1078 | 1101 | int n = count; |
| 1079 | 1102 | while (n-- != 0) { |
| @@ -1086,8 +1109,8 @@ public final class String · 6 unmodified lines | ||
| 1086 | 1109 | if (cs.equals(this)) |
| 1087 | 1110 | return true; |
| 1088 | 1111 | // Argument is a generic CharSequence |
| 1089 | − char v1[] = value; | |
| 1090 | − int i = offset; | |
| 1112 | + char v1[] = toCharArray(); | |
| 1113 | + int i = 0; | |
| 1091 | 1114 | int j = 0; |
| 1092 | 1115 | int n = count; |
| 1093 | 1116 | while (n-- != 0) { |
| @@ -1095,6 +1118,7 @@ public final class String · 1 unmodified line | ||
| 1095 | 1118 | return false; |
| 1096 | 1119 | } |
| 1097 | 1120 | return true; |
| 1121 | + // [Inferno] > | |
| 1098 | 1122 | } |
| 1099 | 1123 | |
| 1100 | 1124 | /** |
| @@ -1126,9 +1150,9 @@ public final class String · 25 unmodified lines | ||
| 1126 | 1150 | * @see #equals(Object) |
| 1127 | 1151 | */ |
| 1128 | 1152 | public boolean equalsIgnoreCase(String anotherString) { |
| 1129 | − return (this == anotherString) ? true : | |
| 1130 | − (anotherString != null) && (anotherString.count == count) && | |
| 1131 | − regionMatches(true, 0, anotherString, 0, count); | |
| 1153 | + // [Inferno] < | |
| 1154 | + return equality(anotherString, true); | |
| 1155 | + // [Inferno] > | |
| 1132 | 1156 | } |
| 1133 | 1157 | |
| 1134 | 1158 | /** |
| @@ -1173,13 +1197,13 @@ public final class String · 38 unmodified lines | ||
| 1173 | 1197 | * lexicographically greater than the string argument. |
| 1174 | 1198 | */ |
| 1175 | 1199 | public int compareTo(String anotherString) { |
| 1176 | − int len1 = count; | |
| 1177 | − int len2 = anotherString.count; | |
| 1200 | + int len1 = length(); | |
| 1201 | + int len2 = anotherString.length(); | |
| 1178 | 1202 | int n = Math.min(len1, len2); |
| 1179 | − char v1[] = value; | |
| 1180 | − char v2[] = anotherString.value; | |
| 1181 | − int i = offset; | |
| 1182 | − int j = anotherString.offset; | |
| 1203 | + char v1[] = toCharArray(); | |
| 1204 | + char v2[] = anotherString.toCharArray(); | |
| 1205 | + int i = 0; | |
| 1206 | + int j = 0; | |
| 1183 | 1207 | |
| 1184 | 1208 | if (i == j) { |
| 1185 | 1209 | int k = i; |
| @@ -1304,21 +1328,9 @@ public final class String · 118 unmodified lines | ||
| 1304 | 1328 | */ |
| 1305 | 1329 | public boolean regionMatches(int toffset, String other, int ooffset, |
| 1306 | 1330 | int len) { |
| 1307 | − char ta[] = value; | |
| 1308 | − int to = offset + toffset; | |
| 1309 | − char pa[] = other.value; | |
| 1310 | − int po = other.offset + ooffset; | |
| 1311 | − // Note: toffset, ooffset, or len might be near -1>>>1. | |
| 1312 | − if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len) | |
| 1313 | − || (ooffset > (long)other.count - len)) { | |
| 1314 | − return false; | |
| 1315 | − } | |
| 1316 | − while (len-- > 0) { | |
| 1317 | − if (ta[to++] != pa[po++]) { | |
| 1318 | − return false; | |
| 1319 | − } | |
| 1320 | − } | |
| 1321 | − return true; | |
| 1331 | + // [Inferno] < | |
| 1332 | + return regionMatches(false, toffset, other, ooffset, len); | |
| 1333 | + // [Inferno] > | |
| 1322 | 1334 | } |
| 1323 | 1335 | |
| 1324 | 1336 | /** |
| @@ -1348,7 +1360,7 @@ public final class String · 23 unmodified lines | ||
| 1348 | 1360 | * integer <i>k</i> less than <tt>len</tt> such that: |
| 1349 | 1361 | * <blockquote><pre> |
| 1350 | 1362 | * Character.toLowerCase(this.charAt(toffset+k)) != |
| 1351 | − Character.toLowerCase(other.charAt(ooffset+k)) | |
| 1363 | + * Character.toLowerCase(other.charAt(ooffset+k)) | |
| 1352 | 1364 | * </pre></blockquote> |
| 1353 | 1365 | * and: |
| 1354 | 1366 | * <blockquote><pre> |
| @@ -1371,45 +1383,10 @@ public final class String · 16 unmodified lines | ||
| 1371 | 1383 | * or case insensitive depends on the <code>ignoreCase</code> |
| 1372 | 1384 | * argument. |
| 1373 | 1385 | */ |
| 1374 | − public boolean regionMatches(boolean ignoreCase, int toffset, | |
| 1375 | − String other, int ooffset, int len) { | |
| 1376 | − char ta[] = value; | |
| 1377 | − int to = offset + toffset; | |
| 1378 | − char pa[] = other.value; | |
| 1379 | − int po = other.offset + ooffset; | |
| 1380 | − // Note: toffset, ooffset, or len might be near -1>>>1. | |
| 1381 | − if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len) || | |
| 1382 | − (ooffset > (long)other.count - len)) { | |
| 1383 | − return false; | |
| 1384 | − } | |
| 1385 | − while (len-- > 0) { | |
| 1386 | − char c1 = ta[to++]; | |
| 1387 | − char c2 = pa[po++]; | |
| 1388 | − if (c1 == c2) { | |
| 1389 | − continue; | |
| 1390 | − } | |
| 1391 | − if (ignoreCase) { | |
| 1392 | − // If characters don't match but case may be ignored, | |
| 1393 | − // try converting both characters to uppercase. | |
| 1394 | − // If the results match, then the comparison scan should | |
| 1395 | − // continue. | |
| 1396 | − char u1 = Character.toUpperCase(c1); | |
| 1397 | − char u2 = Character.toUpperCase(c2); | |
| 1398 | − if (u1 == u2) { | |
| 1399 | − continue; | |
| 1400 | − } | |
| 1401 | − // Unfortunately, conversion to uppercase does not work properly | |
| 1402 | − // for the Georgian alphabet, which has strange rules about case | |
| 1403 | − // conversion. So we need to make one last check before | |
| 1404 | − // exiting. | |
| 1405 | − if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) { | |
| 1406 | − continue; | |
| 1407 | − } | |
| 1408 | − } | |
| 1409 | − return false; | |
| 1410 | − } | |
| 1411 | − return true; | |
| 1412 | − } | |
| 1386 | + // [Inferno] < | |
| 1387 | + public native boolean regionMatches(boolean ignoreCase, int toffset, | |
| 1388 | + String other, int ooffset, int len); | |
| 1389 | + // [Inferno] > | |
| 1413 | 1390 | |
| 1414 | 1391 | /** |
| 1415 | 1392 | * Tests if the substring of this string beginning at the |
| @@ -1429,21 +1406,9 @@ public final class String · 13 unmodified lines | ||
| 1429 | 1406 | * </pre> |
| 1430 | 1407 | */ |
| 1431 | 1408 | public boolean startsWith(String prefix, int toffset) { |
| 1432 | − char ta[] = value; | |
| 1433 | − int to = offset + toffset; | |
| 1434 | − char pa[] = prefix.value; | |
| 1435 | − int po = prefix.offset; | |
| 1436 | − int pc = prefix.count; | |
| 1437 | − // Note: toffset might be near -1>>>1. | |
| 1438 | − if ((toffset < 0) || (toffset > count - pc)) { | |
| 1439 | − return false; | |
| 1440 | − } | |
| 1441 | − while (--pc >= 0) { | |
| 1442 | − if (ta[to++] != pa[po++]) { | |
| 1443 | − return false; | |
| 1444 | − } | |
| 1445 | − } | |
| 1446 | − return true; | |
| 1409 | + // [Inferno] < | |
| 1410 | + return isPrefix(prefix, toffset); | |
| 1411 | + // [Inferno] > | |
| 1447 | 1412 | } |
| 1448 | 1413 | |
| 1449 | 1414 | /** |
| @@ -1460,7 +1425,9 @@ public final class String · 10 unmodified lines | ||
| 1460 | 1425 | * @since 1. 0 |
| 1461 | 1426 | */ |
| 1462 | 1427 | public boolean startsWith(String prefix) { |
| 1463 | − return startsWith(prefix, 0); | |
| 1428 | + // [Inferno] < | |
| 1429 | + return isPrefix(prefix, 0); | |
| 1430 | + // [Inferno] > | |
| 1464 | 1431 | } |
| 1465 | 1432 | |
| 1466 | 1433 | /** |
| @@ -1475,7 +1442,9 @@ public final class String · 8 unmodified lines | ||
| 1475 | 1442 | * as determined by the {@link #equals(Object)} method. |
| 1476 | 1443 | */ |
| 1477 | 1444 | public boolean endsWith(String suffix) { |
| 1478 | − return startsWith(suffix, count - suffix.count); | |
| 1445 | + // [Inferno] < | |
| 1446 | + return isSuffix(suffix); | |
| 1447 | + // [Inferno] > | |
| 1479 | 1448 | } |
| 1480 | 1449 | |
| 1481 | 1450 | /** |
| @@ -1491,20 +1460,9 @@ public final class String · 9 unmodified lines | ||
| 1491 | 1460 | * |
| 1492 | 1461 | * @return a hash code value for this object. |
| 1493 | 1462 | */ |
| 1494 | − public int hashCode() { | |
| 1495 | − int h = hash; | |
| 1496 | − if (h == 0 && count > 0) { | |
| 1497 | − int off = offset; | |
| 1498 | − char val[] = value; | |
| 1499 | − int len = count; | |
| 1500 | − | |
| 1501 | − for (int i = 0; i < len; i++) { | |
| 1502 | − h = 31*h + val[off++]; | |
| 1503 | − } | |
| 1504 | − hash = h; | |
| 1505 | − } | |
| 1506 | − return h; | |
| 1507 | − } | |
| 1463 | + // [Inferno] < | |
| 1464 | + public native int hashCode(); | |
| 1465 | + // [Inferno] > | |
| 1508 | 1466 | |
| 1509 | 1467 | /** |
| 1510 | 1468 | * Returns the index within this string of the first occurrence of |
| @@ -1531,7 +1489,9 @@ public final class String · 20 unmodified lines | ||
| 1531 | 1489 | * <code>-1</code> if the character does not occur. |
| 1532 | 1490 | */ |
| 1533 | 1491 | public int indexOf(int ch) { |
| 1534 | − return indexOf(ch, 0); | |
| 1492 | + // [Inferno] < | |
| 1493 | + return index(ch, 0); | |
| 1494 | + // [Inferno] > | |
| 1535 | 1495 | } |
| 1536 | 1496 | |
| 1537 | 1497 | /** |
| @@ -1574,47 +1534,9 @@ public final class String · 36 unmodified lines | ||
| 1574 | 1534 | * if the character does not occur. |
| 1575 | 1535 | */ |
| 1576 | 1536 | public int indexOf(int ch, int fromIndex) { |
| 1577 | − if (fromIndex < 0) { | |
| 1578 | − fromIndex = 0; | |
| 1579 | − } else if (fromIndex >= count) { | |
| 1580 | − // Note: fromIndex might be near -1>>>1. | |
| 1581 | − return -1; | |
| 1582 | − } | |
| 1583 | − | |
| 1584 | − if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { | |
| 1585 | − // handle most cases here (ch is a BMP code point or a | |
| 1586 | − // negative value (invalid code point)) | |
| 1587 | − final char[] value = this.value; | |
| 1588 | − final int offset = this.offset; | |
| 1589 | − final int max = offset + count; | |
| 1590 | − for (int i = offset + fromIndex; i < max ; i++) { | |
| 1591 | − if (value[i] == ch) { | |
| 1592 | − return i - offset; | |
| 1593 | − } | |
| 1594 | − } | |
| 1595 | − return -1; | |
| 1596 | − } else { | |
| 1597 | − return indexOfSupplementary(ch, fromIndex); | |
| 1598 | − } | |
| 1599 | − } | |
| 1600 | − | |
| 1601 | − /** | |
| 1602 | − * Handles (rare) calls of indexOf with a supplementary character. | |
| 1603 | − */ | |
| 1604 | − private int indexOfSupplementary(int ch, int fromIndex) { | |
| 1605 | − if (Character.isValidCodePoint(ch)) { | |
| 1606 | − final char[] value = this.value; | |
| 1607 | − final int offset = this.offset; | |
| 1608 | − final char hi = Character.highSurrogate(ch); | |
| 1609 | − final char lo = Character.lowSurrogate(ch); | |
| 1610 | − final int max = offset + count - 1; | |
| 1611 | − for (int i = offset + fromIndex; i < max; i++) { | |
| 1612 | − if (value[i] == hi && value[i+1] == lo) { | |
| 1613 | − return i - offset; | |
| 1614 | − } | |
| 1615 | − } | |
| 1616 | − } | |
| 1617 | − return -1; | |
| 1537 | + // [Inferno] < | |
| 1538 | + return index(ch, fromIndex); | |
| 1539 | + // [Inferno] > | |
| 1618 | 1540 | } |
| 1619 | 1541 | |
| 1620 | 1542 | /** |
| @@ -1641,7 +1563,9 @@ public final class String · 20 unmodified lines | ||
| 1641 | 1563 | * <code>-1</code> if the character does not occur. |
| 1642 | 1564 | */ |
| 1643 | 1565 | public int lastIndexOf(int ch) { |
| 1644 | − return lastIndexOf(ch, count - 1); | |
| 1566 | + // [Inferno] < | |
| 1567 | + return rindex(ch, 0, true); | |
| 1568 | + // [Inferno] > | |
| 1645 | 1569 | } |
| 1646 | 1570 | |
| 1647 | 1571 | /** |
| @@ -1679,40 +1603,9 @@ public final class String · 31 unmodified lines | ||
| 1679 | 1603 | * if the character does not occur before that point. |
| 1680 | 1604 | */ |
| 1681 | 1605 | public int lastIndexOf(int ch, int fromIndex) { |
| 1682 | − if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { | |
| 1683 | − // handle most cases here (ch is a BMP code point or a | |
| 1684 | − // negative value (invalid code point)) | |
| 1685 | − final char[] value = this.value; | |
| 1686 | − final int offset = this.offset; | |
| 1687 | − int i = offset + Math.min(fromIndex, count - 1); | |
| 1688 | − for (; i >= offset ; i--) { | |
| 1689 | − if (value[i] == ch) { | |
| 1690 | − return i - offset; | |
| 1691 | − } | |
| 1692 | − } | |
| 1693 | − return -1; | |
| 1694 | − } else { | |
| 1695 | − return lastIndexOfSupplementary(ch, fromIndex); | |
| 1696 | − } | |
| 1697 | − } | |
| 1698 | − | |
| 1699 | − /** | |
| 1700 | − * Handles (rare) calls of lastIndexOf with a supplementary character. | |
| 1701 | − */ | |
| 1702 | − private int lastIndexOfSupplementary(int ch, int fromIndex) { | |
| 1703 | − if (Character.isValidCodePoint(ch)) { | |
| 1704 | − final char[] value = this.value; | |
| 1705 | − final int offset = this.offset; | |
| 1706 | − char hi = Character.highSurrogate(ch); | |
| 1707 | − char lo = Character.lowSurrogate(ch); | |
| 1708 | − int i = offset + Math.min(fromIndex, count - 2); | |
| 1709 | − for (; i >= offset; i--) { | |
| 1710 | − if (value[i] == hi && value[i+1] == lo) { | |
| 1711 | − return i - offset; | |
| 1712 | − } | |
| 1713 | − } | |
| 1714 | − } | |
| 1715 | − return -1; | |
| 1606 | + // [Inferno] < | |
| 1607 | + return rindex(ch, fromIndex, false); | |
| 1608 | + // [Inferno] > | |
| 1716 | 1609 | } |
| 1717 | 1610 | |
| 1718 | 1611 | /** |
| @@ -1730,7 +1623,9 @@ public final class String · 11 unmodified lines | ||
| 1730 | 1623 | * or {@code -1} if there is no such occurrence. |
| 1731 | 1624 | */ |
| 1732 | 1625 | public int indexOf(String str) { |
| 1733 | − return indexOf(str, 0); | |
| 1626 | + // [Inferno] < | |
| 1627 | + return index(str, 0); | |
| 1628 | + // [Inferno] > | |
| 1734 | 1629 | } |
| 1735 | 1630 | |
| 1736 | 1631 | /** |
| @@ -1750,8 +1645,9 @@ public final class String · 13 unmodified lines | ||
| 1750 | 1645 | * or {@code -1} if there is no such occurrence. |
| 1751 | 1646 | */ |
| 1752 | 1647 | public int indexOf(String str, int fromIndex) { |
| 1753 | − return indexOf(value, offset, count, | |
| 1754 | − str.value, str.offset, str.count, fromIndex); | |
| 1648 | + // [Inferno] < | |
| 1649 | + return index(str, fromIndex); | |
| 1650 | + // [Inferno] > | |
| 1755 | 1651 | } |
| 1756 | 1652 | |
| 1757 | 1653 | /** |
| @@ -1821,7 +1717,9 @@ public final class String · 63 unmodified lines | ||
| 1821 | 1717 | * or {@code -1} if there is no such occurrence. |
| 1822 | 1718 | */ |
| 1823 | 1719 | public int lastIndexOf(String str) { |
| 1824 | − return lastIndexOf(str, count); | |
| 1720 | + // [Inferno] < | |
| 1721 | + return rindex(str, 0, true); | |
| 1722 | + // [Inferno] > | |
| 1825 | 1723 | } |
| 1826 | 1724 | |
| 1827 | 1725 | /** |
| @@ -1841,8 +1739,9 @@ public final class String · 13 unmodified lines | ||
| 1841 | 1739 | * or {@code -1} if there is no such occurrence. |
| 1842 | 1740 | */ |
| 1843 | 1741 | public int lastIndexOf(String str, int fromIndex) { |
| 1844 | − return lastIndexOf(value, offset, count, | |
| 1845 | − str.value, str.offset, str.count, fromIndex); | |
| 1742 | + // [Inferno] < | |
| 1743 | + return rindex(str, fromIndex, false); | |
| 1744 | + // [Inferno] > | |
| 1846 | 1745 | } |
| 1847 | 1746 | |
| 1848 | 1747 | /** |
| @@ -1922,7 +1821,7 @@ public final class String · 73 unmodified lines | ||
| 1922 | 1821 | * length of this <code>String</code> object. |
| 1923 | 1822 | */ |
| 1924 | 1823 | public String substring(int beginIndex) { |
| 1925 | − return substring(beginIndex, count); | |
| 1824 | + return substring(beginIndex, length()); | |
| 1926 | 1825 | } |
| 1927 | 1826 | |
| 1928 | 1827 | /** |
| @@ -1947,19 +1846,9 @@ public final class String · 18 unmodified lines | ||
| 1947 | 1846 | * <code>beginIndex</code> is larger than |
| 1948 | 1847 | * <code>endIndex</code>. |
| 1949 | 1848 | */ |
| 1950 | − public String substring(int beginIndex, int endIndex) { | |
| 1951 | − if (beginIndex < 0) { | |
| 1952 | − throw new StringIndexOutOfBoundsException(beginIndex); | |
| 1953 | − } | |
| 1954 | − if (endIndex > count) { | |
| 1955 | − throw new StringIndexOutOfBoundsException(endIndex); | |
| 1956 | − } | |
| 1957 | − if (beginIndex > endIndex) { | |
| 1958 | − throw new StringIndexOutOfBoundsException(endIndex - beginIndex); | |
| 1959 | − } | |
| 1960 | − return ((beginIndex == 0) && (endIndex == count)) ? this : | |
| 1961 | − new String(offset + beginIndex, endIndex - beginIndex, value); | |
| 1962 | − } | |
| 1849 | + // [Inferno] < | |
| 1850 | + public native String substring(int beginIndex, int endIndex); | |
| 1851 | + // [Inferno] > | |
| 1963 | 1852 | |
| 1964 | 1853 | /** |
| 1965 | 1854 | * Returns a new character sequence that is a subsequence of this sequence. |
| @@ -2018,6 +1907,7 @@ public final class String · 52 unmodified lines | ||
| 2018 | 1907 | if (otherLen == 0) { |
| 2019 | 1908 | return this; |
| 2020 | 1909 | } |
| 1910 | + int count = length(); | |
| 2021 | 1911 | char buf[] = new char[count + otherLen]; |
| 2022 | 1912 | getChars(0, count, buf, 0); |
| 2023 | 1913 | str.getChars(0, otherLen, buf, count); |
| @@ -2055,28 +1945,29 @@ public final class String · 31 unmodified lines | ||
| 2055 | 1945 | */ |
| 2056 | 1946 | public String replace(char oldChar, char newChar) { |
| 2057 | 1947 | if (oldChar != newChar) { |
| 2058 | − int len = count; | |
| 1948 | + // [Inferno] < | |
| 2059 | 1949 | int i = -1; |
| 2060 | − char[] val = value; /* avoid getfield opcode */ | |
| 2061 | − int off = offset; /* avoid getfield opcode */ | |
| 1950 | + int len = length(); | |
| 1951 | + char[] val = toCharArray(); | |
| 2062 | 1952 | |
| 2063 | 1953 | while (++i < len) { |
| 2064 | − if (val[off + i] == oldChar) { | |
| 1954 | + if (val[i] == oldChar) { | |
| 2065 | 1955 | break; |
| 2066 | 1956 | } |
| 2067 | 1957 | } |
| 2068 | 1958 | if (i < len) { |
| 2069 | 1959 | char buf[] = new char[len]; |
| 2070 | 1960 | for (int j = 0 ; j < i ; j++) { |
| 2071 | − buf[j] = val[off+j]; | |
| 1961 | + buf[j] = val[j]; | |
| 2072 | 1962 | } |
| 2073 | 1963 | while (i < len) { |
| 2074 | − char c = val[off + i]; | |
| 1964 | + char c = val[i]; | |
| 2075 | 1965 | buf[i] = (c == oldChar) ? newChar : c; |
| 2076 | 1966 | i++; |
| 2077 | 1967 | } |
| 2078 | 1968 | return new String(0, len, buf); |
| 2079 | 1969 | } |
| 1970 | + // [Inferno] > | |
| 2080 | 1971 | } |
| 2081 | 1972 | return this; |
| 2082 | 1973 | } |
| @@ -2317,7 +2208,9 @@ public final class String · 234 unmodified lines | ||
| 2317 | 2208 | the second is not the ascii digit or ascii letter. |
| 2318 | 2209 | */ |
| 2319 | 2210 | char ch = 0; |
| 2320 | − if (((regex.count == 1 && | |
| 2211 | + // [Inferno] < | |
| 2212 | + int count = length(); | |
| 2213 | + if (((regex.length() == 1 && | |
| 2321 | 2214 | ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || |
| 2322 | 2215 | (regex.length() == 2 && |
| 2323 | 2216 | regex.charAt(0) == '\\' && |
| @@ -2359,6 +2252,7 @@ public final class String · 35 unmodified lines | ||
| 2359 | 2252 | return list.subList(0, resultSize).toArray(result); |
| 2360 | 2253 | } |
| 2361 | 2254 | return Pattern.compile(regex).split(this, limit); |
| 2255 | + // [Inferno] > | |
| 2362 | 2256 | } |
| 2363 | 2257 | |
| 2364 | 2258 | /** |
| @@ -2456,97 +2350,9 @@ public final class String · 91 unmodified lines | ||
| 2456 | 2350 | * @since 1.1 |
| 2457 | 2351 | */ |
| 2458 | 2352 | public String toLowerCase(Locale locale) { |
| 2459 | − if (locale == null) { | |
| 2460 | − throw new NullPointerException(); | |
| 2461 | − } | |
| 2462 | − | |
| 2463 | − int firstUpper; | |
| 2464 | − | |
| 2465 | − /* Now check if there are any characters that need to be changed. */ | |
| 2466 | − scan: { | |
| 2467 | − for (firstUpper = 0 ; firstUpper < count; ) { | |
| 2468 | − char c = value[offset+firstUpper]; | |
| 2469 | − if ((c >= Character.MIN_HIGH_SURROGATE) && | |
| 2470 | − (c <= Character.MAX_HIGH_SURROGATE)) { | |
| 2471 | − int supplChar = codePointAt(firstUpper); | |
| 2472 | − if (supplChar != Character.toLowerCase(supplChar)) { | |
| 2473 | − break scan; | |
| 2474 | − } | |
| 2475 | − firstUpper += Character.charCount(supplChar); | |
| 2476 | − } else { | |
| 2477 | − if (c != Character.toLowerCase(c)) { | |
| 2478 | − break scan; | |
| 2479 | − } | |
| 2480 | − firstUpper++; | |
| 2481 | − } | |
| 2482 | − } | |
| 2483 | − return this; | |
| 2484 | − } | |
| 2485 | − | |
| 2486 | − char[] result = new char[count]; | |
| 2487 | − int resultOffset = 0; /* result may grow, so i+resultOffset | |
| 2488 | − * is the write location in result */ | |
| 2489 | − | |
| 2490 | − /* Just copy the first few lowerCase characters. */ | |
| 2491 | − System.arraycopy(value, offset, result, 0, firstUpper); | |
| 2492 | − | |
| 2493 | − String lang = locale.getLanguage(); | |
| 2494 | − boolean localeDependent = | |
| 2495 | − (lang == "tr" || lang == "az" || lang == "lt"); | |
| 2496 | − char[] lowerCharArray; | |
| 2497 | − int lowerChar; | |
| 2498 | − int srcChar; | |
| 2499 | − int srcCount; | |
| 2500 | − for (int i = firstUpper; i < count; i += srcCount) { | |
| 2501 | − srcChar = (int)value[offset+i]; | |
| 2502 | − if ((char)srcChar >= Character.MIN_HIGH_SURROGATE && | |
| 2503 | − (char)srcChar <= Character.MAX_HIGH_SURROGATE) { | |
| 2504 | − srcChar = codePointAt(i); | |
| 2505 | − srcCount = Character.charCount(srcChar); | |
| 2506 | − } else { | |
| 2507 | − srcCount = 1; | |
| 2508 | − } | |
| 2509 | − if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA | |
| 2510 | − lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale); | |
| 2511 | − } else if (srcChar == '\u0130') { // LATIN CAPITAL LETTER I DOT | |
| 2512 | − lowerChar = Character.ERROR; | |
| 2513 | − } else { | |
| 2514 | − lowerChar = Character.toLowerCase(srcChar); | |
| 2515 | − } | |
| 2516 | − if ((lowerChar == Character.ERROR) || | |
| 2517 | − (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) { | |
| 2518 | − if (lowerChar == Character.ERROR) { | |
| 2519 | − if (!localeDependent && srcChar == '\u0130') { | |
| 2520 | − lowerCharArray = | |
| 2521 | − ConditionalSpecialCasing.toLowerCaseCharArray(this, i, Locale.ENGLISH); | |
| 2522 | − } else { | |
| 2523 | − lowerCharArray = | |
| 2524 | − ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale); | |
| 2525 | − } | |
| 2526 | − } else if (srcCount == 2) { | |
| 2527 | − resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount; | |
| 2528 | − continue; | |
| 2529 | − } else { | |
| 2530 | − lowerCharArray = Character.toChars(lowerChar); | |
| 2531 | − } | |
| 2532 | − | |
| 2533 | − /* Grow result if needed */ | |
| 2534 | − int mapLen = lowerCharArray.length; | |
| 2535 | − if (mapLen > srcCount) { | |
| 2536 | − char[] result2 = new char[result.length + mapLen - srcCount]; | |
| 2537 | − System.arraycopy(result, 0, result2, 0, | |
| 2538 | − i + resultOffset); | |
| 2539 | − result = result2; | |
| 2540 | − } | |
| 2541 | − for (int x=0; x<mapLen; ++x) { | |
| 2542 | − result[i+resultOffset+x] = lowerCharArray[x]; | |
| 2543 | − } | |
| 2544 | − resultOffset += (mapLen - srcCount); | |
| 2545 | − } else { | |
| 2546 | − result[i+resultOffset] = (char)lowerChar; | |
| 2547 | − } | |
| 2548 | − } | |
| 2549 | − return new String(0, count+resultOffset, result); | |
| 2353 | + // [Inferno] < | |
| 2354 | + return lowercase(); | |
| 2355 | + // [Inferno] > | |
| 2550 | 2356 | } |
| 2551 | 2357 | |
| 2552 | 2358 | /** |
| @@ -2569,7 +2375,7 @@ public final class String · 16 unmodified lines | ||
| 2569 | 2375 | * @see java.lang.String#toLowerCase(Locale) |
| 2570 | 2376 | */ |
| 2571 | 2377 | public String toLowerCase() { |
| 2572 | − return toLowerCase(Locale.getDefault()); | |
| 2378 | + return lowercase(); | |
| 2573 | 2379 | } |
| 2574 | 2380 | |
| 2575 | 2381 | /** |
| @@ -2621,95 +2427,9 @@ public final class String · 45 unmodified lines | ||
| 2621 | 2427 | * @since 1.1 |
| 2622 | 2428 | */ |
| 2623 | 2429 | public String toUpperCase(Locale locale) { |
| 2624 | − if (locale == null) { | |
| 2625 | − throw new NullPointerException(); | |
| 2626 | − } | |
| 2627 | − | |
| 2628 | − int firstLower; | |
| 2629 | − | |
| 2630 | − /* Now check if there are any characters that need to be changed. */ | |
| 2631 | − scan: { | |
| 2632 | − for (firstLower = 0 ; firstLower < count; ) { | |
| 2633 | − int c = (int)value[offset+firstLower]; | |
| 2634 | − int srcCount; | |
| 2635 | − if ((c >= Character.MIN_HIGH_SURROGATE) && | |
| 2636 | − (c <= Character.MAX_HIGH_SURROGATE)) { | |
| 2637 | − c = codePointAt(firstLower); | |
| 2638 | − srcCount = Character.charCount(c); | |
| 2639 | − } else { | |
| 2640 | − srcCount = 1; | |
| 2641 | − } | |
| 2642 | − int upperCaseChar = Character.toUpperCaseEx(c); | |
| 2643 | − if ((upperCaseChar == Character.ERROR) || | |
| 2644 | − (c != upperCaseChar)) { | |
| 2645 | − break scan; | |
| 2646 | − } | |
| 2647 | − firstLower += srcCount; | |
| 2648 | − } | |
| 2649 | − return this; | |
| 2650 | − } | |
| 2651 | − | |
| 2652 | − char[] result = new char[count]; /* may grow */ | |
| 2653 | − int resultOffset = 0; /* result may grow, so i+resultOffset | |
| 2654 | − * is the write location in result */ | |
| 2655 | − | |
| 2656 | − /* Just copy the first few upperCase characters. */ | |
| 2657 | − System.arraycopy(value, offset, result, 0, firstLower); | |
| 2658 | − | |
| 2659 | − String lang = locale.getLanguage(); | |
| 2660 | − boolean localeDependent = | |
| 2661 | − (lang == "tr" || lang == "az" || lang == "lt"); | |
| 2662 | − char[] upperCharArray; | |
| 2663 | − int upperChar; | |
| 2664 | − int srcChar; | |
| 2665 | − int srcCount; | |
| 2666 | − for (int i = firstLower; i < count; i += srcCount) { | |
| 2667 | − srcChar = (int)value[offset+i]; | |
| 2668 | − if ((char)srcChar >= Character.MIN_HIGH_SURROGATE && | |
| 2669 | − (char)srcChar <= Character.MAX_HIGH_SURROGATE) { | |
| 2670 | − srcChar = codePointAt(i); | |
| 2671 | − srcCount = Character.charCount(srcChar); | |
| 2672 | − } else { | |
| 2673 | − srcCount = 1; | |
| 2674 | − } | |
| 2675 | − if (localeDependent) { | |
| 2676 | − upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale); | |
| 2677 | − } else { | |
| 2678 | − upperChar = Character.toUpperCaseEx(srcChar); | |
| 2679 | − } | |
| 2680 | − if ((upperChar == Character.ERROR) || | |
| 2681 | − (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) { | |
| 2682 | − if (upperChar == Character.ERROR) { | |
| 2683 | − if (localeDependent) { | |
| 2684 | − upperCharArray = | |
| 2685 | − ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale); | |
| 2686 | − } else { | |
| 2687 | − upperCharArray = Character.toUpperCaseCharArray(srcChar); | |
| 2688 | − } | |
| 2689 | − } else if (srcCount == 2) { | |
| 2690 | − resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount; | |
| 2691 | − continue; | |
| 2692 | − } else { | |
| 2693 | − upperCharArray = Character.toChars(upperChar); | |
| 2694 | − } | |
| 2695 | − | |
| 2696 | − /* Grow result if needed */ | |
| 2697 | − int mapLen = upperCharArray.length; | |
| 2698 | − if (mapLen > srcCount) { | |
| 2699 | − char[] result2 = new char[result.length + mapLen - srcCount]; | |
| 2700 | − System.arraycopy(result, 0, result2, 0, | |
| 2701 | − i + resultOffset); | |
| 2702 | − result = result2; | |
| 2703 | − } | |
| 2704 | − for (int x=0; x<mapLen; ++x) { | |
| 2705 | − result[i+resultOffset+x] = upperCharArray[x]; | |
| 2706 | − } | |
| 2707 | − resultOffset += (mapLen - srcCount); | |
| 2708 | − } else { | |
| 2709 | − result[i+resultOffset] = (char)upperChar; | |
| 2710 | − } | |
| 2711 | − } | |
| 2712 | − return new String(0, count+resultOffset, result); | |
| 2430 | + // [Inferno] < | |
| 2431 | + return uppercase(); | |
| 2432 | + // [Inferno] > | |
| 2713 | 2433 | } |
| 2714 | 2434 | |
| 2715 | 2435 | /** |
| @@ -2732,7 +2452,7 @@ public final class String · 16 unmodified lines | ||
| 2732 | 2452 | * @see java.lang.String#toUpperCase(Locale) |
| 2733 | 2453 | */ |
| 2734 | 2454 | public String toUpperCase() { |
| 2735 | − return toUpperCase(Locale.getDefault()); | |
| 2455 | + return uppercase(); | |
| 2736 | 2456 | } |
| 2737 | 2457 | |
| 2738 | 2458 | /** |
| @@ -2767,18 +2487,19 @@ public final class String · 28 unmodified lines | ||
| 2767 | 2487 | * trailing white space. |
| 2768 | 2488 | */ |
| 2769 | 2489 | public String trim() { |
| 2770 | − int len = count; | |
| 2490 | + // [Inferno] < | |
| 2771 | 2491 | int st = 0; |
| 2772 | − int off = offset; /* avoid getfield opcode */ | |
| 2773 | − char[] val = value; /* avoid getfield opcode */ | |
| 2492 | + int len = length(); | |
| 2493 | + char[] val = toCharArray(); | |
| 2774 | 2494 | |
| 2775 | − while ((st < len) && (val[off + st] <= ' ')) { | |
| 2495 | + while ((st < len) && (val[st] <= ' ')) { | |
| 2776 | 2496 | st++; |
| 2777 | 2497 | } |
| 2778 | − while ((st < len) && (val[off + len - 1] <= ' ')) { | |
| 2498 | + while ((st < len) && (val[len - 1] <= ' ')) { | |
| 2779 | 2499 | len--; |
| 2780 | 2500 | } |
| 2781 | − return ((st > 0) || (len < count)) ? substring(st, len) : this; | |
| 2501 | + return ((st > 0) || (len < length())) ? substring(st, len) : this; | |
| 2502 | + // [Inferno] > | |
| 2782 | 2503 | } |
| 2783 | 2504 | |
| 2784 | 2505 | /** |
| @@ -2798,6 +2519,9 @@ public final class String · 13 unmodified lines | ||
| 2798 | 2519 | * the character sequence represented by this string. |
| 2799 | 2520 | */ |
| 2800 | 2521 | public char[] toCharArray() { |
| 2522 | + // [Inferno] < | |
| 2523 | + int count = length(); | |
| 2524 | + // [Inferno] > | |
| 2801 | 2525 | char result[] = new char[count]; |
| 2802 | 2526 | getChars(0, count, result, 0); |
| 2803 | 2527 | return result; |
| @@ -3074,4 +2798,20 @@ public final class String · 270 unmodified lines | ||
| 3074 | 2798 | */ |
| 3075 | 2799 | public native String intern(); |
| 3076 | 2800 | |
| 2801 | + // [Inferno] Some native platform-specific methods | |
| 2802 | + | |
| 2803 | + private native boolean equality(String other, boolean ignoreCase); | |
| 2804 | + | |
| 2805 | + private native void fill(char[] chars, int idx, int count); | |
| 2806 | + private native boolean isPrefix(String str, int index); | |
| 2807 | + private native boolean isSuffix(String str); | |
| 2808 | + private native String uppercase(); | |
| 2809 | + private native String lowercase(); | |
| 2810 | + | |
| 2811 | + private native int index(String str, int begin); | |
| 2812 | + private native int index(int ch, int begin); | |
| 2813 | + | |
| 2814 | + private native int rindex(String str, int begin, boolean fromend); | |
| 2815 | + private native int rindex(int ch, int begin, boolean fromend); | |
| 2816 | + | |
| 3077 | 2817 | } |