1047 }
1048
1049 private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
1050 int len = length();
1051 if (len != sb.length()) {
1052 return false;
1053 }
1054 byte v1[] = value;
1055 byte v2[] = sb.getValue();
1056 if (coder() == sb.getCoder()) {
1057 int n = v1.length;
1058 for (int i = 0; i < n; i++) {
1059 if (v1[i] != v2[i]) {
1060 return false;
1061 }
1062 }
1063 } else {
1064 if (!isLatin1()) { // utf16 str and latin1 abs can never be "equal"
1065 return false;
1066 }
1067 for (int i = 0; i < len; i++) {
1068 if ((char)(v1[i] & 0xff) != StringUTF16.getChar(v2, i)) {
1069 return false;
1070 }
1071 }
1072 }
1073 return true;
1074 }
1075
1076 /**
1077 * Compares this string to the specified {@code CharSequence}. The
1078 * result is {@code true} if and only if this {@code String} represents the
1079 * same sequence of char values as the specified sequence. Note that if the
1080 * {@code CharSequence} is a {@code StringBuffer} then the method
1081 * synchronizes on it.
1082 *
1083 * <p>For finer-grained String comparison, refer to
1084 * {@link java.text.Collator}.
1085 *
1086 * @param cs
1717 * @param srcCoder the coder of the source string.
1718 * @param srcCount length of the source string.
1719 * @param tgtStr the characters being searched for.
1720 * @param fromIndex the index to begin searching from.
1721 */
1722 static int indexOf(byte[] src, byte srcCoder, int srcCount,
1723 String tgtStr, int fromIndex) {
1724 byte[] tgt = tgtStr.value;
1725 byte tgtCoder = tgtStr.coder();
1726 int tgtCount = tgtStr.length();
1727
1728 if (fromIndex >= srcCount) {
1729 return (tgtCount == 0 ? srcCount : -1);
1730 }
1731 if (fromIndex < 0) {
1732 fromIndex = 0;
1733 }
1734 if (tgtCount == 0) {
1735 return fromIndex;
1736 }
1737 if (srcCoder == tgtCoder) {
1738 return srcCoder == LATIN1
1739 ? StringLatin1.indexOf(src, srcCount, tgt, tgtCount, fromIndex)
1740 : StringUTF16.indexOf(src, srcCount, tgt, tgtCount, fromIndex);
1741 }
1742 if (srcCoder == LATIN1) { // && tgtCoder == UTF16
1743 return -1;
1744 }
1745 // srcCoder == UTF16 && tgtCoder == LATIN1) {
1746 return StringUTF16.indexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex);
1747 }
1748
1749 /**
1750 * Returns the index within this string of the last occurrence of the
1751 * specified substring. The last occurrence of the empty string ""
1752 * is considered to occur at the index value {@code this.length()}.
1753 *
1754 * <p>The returned index is the largest value {@code k} for which:
1755 * <pre>{@code
1756 * this.startsWith(str, k)
1777 * If no such value of {@code k} exists, then {@code -1} is returned.
1778 *
1779 * @param str the substring to search for.
1780 * @param fromIndex the index to start the search from.
1781 * @return the index of the last occurrence of the specified substring,
1782 * searching backward from the specified index,
1783 * or {@code -1} if there is no such occurrence.
1784 */
1785 public int lastIndexOf(String str, int fromIndex) {
1786 return lastIndexOf(value, coder(), length(), str, fromIndex);
1787 }
1788
1789 /**
1790 * Code shared by String and AbstractStringBuilder to do searches. The
1791 * source is the character array being searched, and the target
1792 * is the string being searched for.
1793 *
1794 * @param src the characters being searched.
1795 * @param srcCoder coder handles the mapping between bytes/chars
1796 * @param srcCount count of the source string.
1797 * @param tgt the characters being searched for.
1798 * @param fromIndex the index to begin searching from.
1799 */
1800 static int lastIndexOf(byte[] src, byte srcCoder, int srcCount,
1801 String tgtStr, int fromIndex) {
1802 byte[] tgt = tgtStr.value;
1803 byte tgtCoder = tgtStr.coder();
1804 int tgtCount = tgtStr.length();
1805 /*
1806 * Check arguments; return immediately where possible. For
1807 * consistency, don't check for null str.
1808 */
1809 int rightIndex = srcCount - tgtCount;
1810 if (fromIndex < 0) {
1811 return -1;
1812 }
1813 if (fromIndex > rightIndex) {
1814 fromIndex = rightIndex;
1815 }
1816 /* Empty string always matches. */
1817 if (tgtCount == 0) {
1818 return fromIndex;
1819 }
1820 if (srcCoder == tgtCoder) {
1821 return srcCoder == LATIN1
1822 ? StringLatin1.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex)
1823 : StringUTF16.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex);
1824 }
1825 if (srcCoder == LATIN1) { // && tgtCoder == UTF16
1826 return -1;
1827 }
1828 // srcCoder == UTF16 && tgtCoder == LATIN1
1829 int min = tgtCount - 1;
1830 int i = min + fromIndex;
1831 int strLastIndex = tgtCount - 1;
1832
1833 char strLastChar = (char)(tgt[strLastIndex] & 0xff);
1834 startSearchForLastChar:
1835 while (true) {
3063 this.coder = coder;
3064 }
3065
3066 byte coder() {
3067 return COMPACT_STRINGS ? coder : UTF16;
3068 }
3069
3070 private boolean isLatin1() {
3071 return COMPACT_STRINGS && coder == LATIN1;
3072 }
3073
3074 static final byte LATIN1 = 0;
3075 static final byte UTF16 = 1;
3076
3077 /*
3078 * StringIndexOutOfBoundsException if {@code index} is
3079 * negative or greater than or equal to {@code length}.
3080 */
3081 static void checkIndex(int index, int length) {
3082 if (index < 0 || index >= length) {
3083 throw new StringIndexOutOfBoundsException("index " + index);
3084 }
3085 }
3086
3087 /*
3088 * StringIndexOutOfBoundsException if {@code offset}
3089 * is negative or greater than {@code length}.
3090 */
3091 static void checkOffset(int offset, int length) {
3092 if (offset < 0 || offset > length) {
3093 throw new StringIndexOutOfBoundsException("offset " + offset +
3094 ",length " + length);
3095 }
3096 }
3097
3098 /*
3099 * Check {@code offset}, {@code count} against {@code 0} and {@code length}
3100 * bounds.
3101 *
3102 * @throws StringIndexOutOfBoundsException
3103 * If {@code offset} is negative, {@code count} is negative,
3104 * or {@code offset} is greater than {@code length - count}
3105 */
3106 static void checkBoundsOffCount(int offset, int count, int length) {
3107 if (offset < 0 || count < 0 || offset > length - count) {
3108 throw new StringIndexOutOfBoundsException(
3109 "offset " + offset + ", count " + count + ", length " + length);
3110 }
3111 }
3112
3113 /*
3114 * Check {@code begin}, {@code end} against {@code 0} and {@code length}
3115 * bounds.
3116 *
3117 * @throws StringIndexOutOfBoundsException
3118 * If {@code begin} is negative, {@code begin} is greater than
3119 * {@code end}, or {@code end} is greater than {@code length}.
3120 */
3121 private static void checkBoundsBeginEnd(int begin, int end, int length) {
3122 if (begin < 0 || begin > end || end > length) {
3123 throw new StringIndexOutOfBoundsException(
3124 "begin " + begin + ", end " + end + ", length " + length);
3125 }
3126 }
3127 }
|
1047 }
1048
1049 private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
1050 int len = length();
1051 if (len != sb.length()) {
1052 return false;
1053 }
1054 byte v1[] = value;
1055 byte v2[] = sb.getValue();
1056 if (coder() == sb.getCoder()) {
1057 int n = v1.length;
1058 for (int i = 0; i < n; i++) {
1059 if (v1[i] != v2[i]) {
1060 return false;
1061 }
1062 }
1063 } else {
1064 if (!isLatin1()) { // utf16 str and latin1 abs can never be "equal"
1065 return false;
1066 }
1067 checkOffset(len, v2.length >> 1);
1068 for (int i = 0; i < len; i++) {
1069 if ((char)(v1[i] & 0xff) != StringUTF16.getChar(v2, i)) {
1070 return false;
1071 }
1072 }
1073 }
1074 return true;
1075 }
1076
1077 /**
1078 * Compares this string to the specified {@code CharSequence}. The
1079 * result is {@code true} if and only if this {@code String} represents the
1080 * same sequence of char values as the specified sequence. Note that if the
1081 * {@code CharSequence} is a {@code StringBuffer} then the method
1082 * synchronizes on it.
1083 *
1084 * <p>For finer-grained String comparison, refer to
1085 * {@link java.text.Collator}.
1086 *
1087 * @param cs
1718 * @param srcCoder the coder of the source string.
1719 * @param srcCount length of the source string.
1720 * @param tgtStr the characters being searched for.
1721 * @param fromIndex the index to begin searching from.
1722 */
1723 static int indexOf(byte[] src, byte srcCoder, int srcCount,
1724 String tgtStr, int fromIndex) {
1725 byte[] tgt = tgtStr.value;
1726 byte tgtCoder = tgtStr.coder();
1727 int tgtCount = tgtStr.length();
1728
1729 if (fromIndex >= srcCount) {
1730 return (tgtCount == 0 ? srcCount : -1);
1731 }
1732 if (fromIndex < 0) {
1733 fromIndex = 0;
1734 }
1735 if (tgtCount == 0) {
1736 return fromIndex;
1737 }
1738 if (tgtCount > srcCount) {
1739 return -1;
1740 }
1741 if (srcCoder == tgtCoder) {
1742 return srcCoder == LATIN1
1743 ? StringLatin1.indexOf(src, srcCount, tgt, tgtCount, fromIndex)
1744 : StringUTF16.indexOf(src, srcCount, tgt, tgtCount, fromIndex);
1745 }
1746 if (srcCoder == LATIN1) { // && tgtCoder == UTF16
1747 return -1;
1748 }
1749 // srcCoder == UTF16 && tgtCoder == LATIN1) {
1750 return StringUTF16.indexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex);
1751 }
1752
1753 /**
1754 * Returns the index within this string of the last occurrence of the
1755 * specified substring. The last occurrence of the empty string ""
1756 * is considered to occur at the index value {@code this.length()}.
1757 *
1758 * <p>The returned index is the largest value {@code k} for which:
1759 * <pre>{@code
1760 * this.startsWith(str, k)
1781 * If no such value of {@code k} exists, then {@code -1} is returned.
1782 *
1783 * @param str the substring to search for.
1784 * @param fromIndex the index to start the search from.
1785 * @return the index of the last occurrence of the specified substring,
1786 * searching backward from the specified index,
1787 * or {@code -1} if there is no such occurrence.
1788 */
1789 public int lastIndexOf(String str, int fromIndex) {
1790 return lastIndexOf(value, coder(), length(), str, fromIndex);
1791 }
1792
1793 /**
1794 * Code shared by String and AbstractStringBuilder to do searches. The
1795 * source is the character array being searched, and the target
1796 * is the string being searched for.
1797 *
1798 * @param src the characters being searched.
1799 * @param srcCoder coder handles the mapping between bytes/chars
1800 * @param srcCount count of the source string.
1801 * @param tgtStr the characters being searched for.
1802 * @param fromIndex the index to begin searching from.
1803 */
1804 static int lastIndexOf(byte[] src, byte srcCoder, int srcCount,
1805 String tgtStr, int fromIndex) {
1806 byte[] tgt = tgtStr.value;
1807 byte tgtCoder = tgtStr.coder();
1808 int tgtCount = tgtStr.length();
1809 /*
1810 * Check arguments; return immediately where possible. For
1811 * consistency, don't check for null str.
1812 */
1813 int rightIndex = srcCount - tgtCount;
1814 if (fromIndex > rightIndex) {
1815 fromIndex = rightIndex;
1816 }
1817 if (fromIndex < 0) {
1818 return -1;
1819 }
1820 /* Empty string always matches. */
1821 if (tgtCount == 0) {
1822 return fromIndex;
1823 }
1824 if (srcCoder == tgtCoder) {
1825 return srcCoder == LATIN1
1826 ? StringLatin1.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex)
1827 : StringUTF16.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex);
1828 }
1829 if (srcCoder == LATIN1) { // && tgtCoder == UTF16
1830 return -1;
1831 }
1832 // srcCoder == UTF16 && tgtCoder == LATIN1
1833 int min = tgtCount - 1;
1834 int i = min + fromIndex;
1835 int strLastIndex = tgtCount - 1;
1836
1837 char strLastChar = (char)(tgt[strLastIndex] & 0xff);
1838 startSearchForLastChar:
1839 while (true) {
3067 this.coder = coder;
3068 }
3069
3070 byte coder() {
3071 return COMPACT_STRINGS ? coder : UTF16;
3072 }
3073
3074 private boolean isLatin1() {
3075 return COMPACT_STRINGS && coder == LATIN1;
3076 }
3077
3078 static final byte LATIN1 = 0;
3079 static final byte UTF16 = 1;
3080
3081 /*
3082 * StringIndexOutOfBoundsException if {@code index} is
3083 * negative or greater than or equal to {@code length}.
3084 */
3085 static void checkIndex(int index, int length) {
3086 if (index < 0 || index >= length) {
3087 throw new StringIndexOutOfBoundsException("index " + index +
3088 ", length " + length);
3089 }
3090 }
3091
3092 /*
3093 * StringIndexOutOfBoundsException if {@code offset}
3094 * is negative or greater than {@code length}.
3095 */
3096 static void checkOffset(int offset, int length) {
3097 if (offset < 0 || offset > length) {
3098 throw new StringIndexOutOfBoundsException("offset " + offset +
3099 ",length " + length);
3100 }
3101 }
3102
3103 /*
3104 * Check {@code offset}, {@code count} against {@code 0} and {@code length}
3105 * bounds.
3106 *
3107 * @throws StringIndexOutOfBoundsException
3108 * If {@code offset} is negative, {@code count} is negative,
3109 * or {@code offset} is greater than {@code length - count}
3110 */
3111 static void checkBoundsOffCount(int offset, int count, int length) {
3112 if (offset < 0 || count < 0 || offset > length - count) {
3113 throw new StringIndexOutOfBoundsException(
3114 "offset " + offset + ", count " + count + ", length " + length);
3115 }
3116 }
3117
3118 /*
3119 * Check {@code begin}, {@code end} against {@code 0} and {@code length}
3120 * bounds.
3121 *
3122 * @throws StringIndexOutOfBoundsException
3123 * If {@code begin} is negative, {@code begin} is greater than
3124 * {@code end}, or {@code end} is greater than {@code length}.
3125 */
3126 static void checkBoundsBeginEnd(int begin, int end, int length) {
3127 if (begin < 0 || begin > end || end > length) {
3128 throw new StringIndexOutOfBoundsException(
3129 "begin " + begin + ", end " + end + ", length " + length);
3130 }
3131 }
3132 }
|