mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-24 04:54:40 +02:00
6924259: Remove offset and count fields from java.lang.String
Removes the use of shared character array buffers by String along with the two fields needed to support the use of shared buffers. Reviewed-by: alanb, mduigou, forax, briangoetz
This commit is contained in:
parent
4747e218b3
commit
f55750d05a
4 changed files with 237 additions and 291 deletions
|
@ -381,7 +381,7 @@ public final class Integer extends Number implements Comparable<Integer> {
|
||||||
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
|
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
|
||||||
char[] buf = new char[size];
|
char[] buf = new char[size];
|
||||||
getChars(i, size, buf);
|
getChars(i, size, buf);
|
||||||
return new String(0, size, buf);
|
return new String(buf, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -373,7 +373,7 @@ public final class Long extends Number implements Comparable<Long> {
|
||||||
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
|
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
|
||||||
char[] buf = new char[size];
|
char[] buf = new char[size];
|
||||||
getChars(i, size, buf);
|
getChars(i, size, buf);
|
||||||
return new String(0, size, buf);
|
return new String(buf, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -108,17 +108,10 @@ import java.util.regex.PatternSyntaxException;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public final class String
|
public final class String
|
||||||
implements java.io.Serializable, Comparable<String>, CharSequence
|
implements java.io.Serializable, Comparable<String>, CharSequence {
|
||||||
{
|
|
||||||
/** The value is used for character storage. */
|
/** The value is used for character storage. */
|
||||||
private final char value[];
|
private final char value[];
|
||||||
|
|
||||||
/** The offset is the first index of the storage that is used. */
|
|
||||||
private final int offset;
|
|
||||||
|
|
||||||
/** The count is the number of characters in the String. */
|
|
||||||
private final int count;
|
|
||||||
|
|
||||||
/** Cache the hash code for the string */
|
/** Cache the hash code for the string */
|
||||||
private int hash; // Default to 0
|
private int hash; // Default to 0
|
||||||
|
|
||||||
|
@ -146,8 +139,6 @@ public final class String
|
||||||
* unnecessary since Strings are immutable.
|
* unnecessary since Strings are immutable.
|
||||||
*/
|
*/
|
||||||
public String() {
|
public String() {
|
||||||
this.offset = 0;
|
|
||||||
this.count = 0;
|
|
||||||
this.value = new char[0];
|
this.value = new char[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,23 +153,8 @@ public final class String
|
||||||
* A {@code String}
|
* A {@code String}
|
||||||
*/
|
*/
|
||||||
public String(String original) {
|
public String(String original) {
|
||||||
int size = original.count;
|
this.value = original.value;
|
||||||
char[] originalValue = original.value;
|
this.hash = original.hash;
|
||||||
char[] v;
|
|
||||||
if (originalValue.length > size) {
|
|
||||||
// The array representing the String is bigger than the new
|
|
||||||
// String itself. Perhaps this constructor is being called
|
|
||||||
// in order to trim the baggage, so make a copy of the array.
|
|
||||||
int off = original.offset;
|
|
||||||
v = Arrays.copyOfRange(originalValue, off, off+size);
|
|
||||||
} else {
|
|
||||||
// The array representing the String is the same
|
|
||||||
// size as the String, so no point in making a copy.
|
|
||||||
v = originalValue;
|
|
||||||
}
|
|
||||||
this.offset = 0;
|
|
||||||
this.count = size;
|
|
||||||
this.value = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,10 +167,7 @@ public final class String
|
||||||
* The initial value of the string
|
* The initial value of the string
|
||||||
*/
|
*/
|
||||||
public String(char value[]) {
|
public String(char value[]) {
|
||||||
int size = value.length;
|
this.value = Arrays.copyOf(value, value.length);
|
||||||
this.offset = 0;
|
|
||||||
this.count = size;
|
|
||||||
this.value = Arrays.copyOf(value, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -229,8 +202,6 @@ public final class String
|
||||||
if (offset > value.length - count) {
|
if (offset > value.length - count) {
|
||||||
throw new StringIndexOutOfBoundsException(offset + count);
|
throw new StringIndexOutOfBoundsException(offset + count);
|
||||||
}
|
}
|
||||||
this.offset = 0;
|
|
||||||
this.count = count;
|
|
||||||
this.value = Arrays.copyOfRange(value, offset, offset+count);
|
this.value = Arrays.copyOfRange(value, offset, offset+count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,8 +270,6 @@ public final class String
|
||||||
}
|
}
|
||||||
|
|
||||||
this.value = v;
|
this.value = v;
|
||||||
this.count = n;
|
|
||||||
this.offset = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -357,8 +326,6 @@ public final class String
|
||||||
value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
|
value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.offset = 0;
|
|
||||||
this.count = count;
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,15 +411,11 @@ public final class String
|
||||||
* @since JDK1.1
|
* @since JDK1.1
|
||||||
*/
|
*/
|
||||||
public String(byte bytes[], int offset, int length, String charsetName)
|
public String(byte bytes[], int offset, int length, String charsetName)
|
||||||
throws UnsupportedEncodingException
|
throws UnsupportedEncodingException {
|
||||||
{
|
|
||||||
if (charsetName == null)
|
if (charsetName == null)
|
||||||
throw new NullPointerException("charsetName");
|
throw new NullPointerException("charsetName");
|
||||||
checkBounds(bytes, offset, length);
|
checkBounds(bytes, offset, length);
|
||||||
char[] v = StringCoding.decode(charsetName, bytes, offset, length);
|
this.value = StringCoding.decode(charsetName, bytes, offset, length);
|
||||||
this.offset = 0;
|
|
||||||
this.count = v.length;
|
|
||||||
this.value = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -489,10 +452,7 @@ public final class String
|
||||||
if (charset == null)
|
if (charset == null)
|
||||||
throw new NullPointerException("charset");
|
throw new NullPointerException("charset");
|
||||||
checkBounds(bytes, offset, length);
|
checkBounds(bytes, offset, length);
|
||||||
char[] v = StringCoding.decode(charset, bytes, offset, length);
|
this.value = StringCoding.decode(charset, bytes, offset, length);
|
||||||
this.offset = 0;
|
|
||||||
this.count = v.length;
|
|
||||||
this.value = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -519,8 +479,7 @@ public final class String
|
||||||
* @since JDK1.1
|
* @since JDK1.1
|
||||||
*/
|
*/
|
||||||
public String(byte bytes[], String charsetName)
|
public String(byte bytes[], String charsetName)
|
||||||
throws UnsupportedEncodingException
|
throws UnsupportedEncodingException {
|
||||||
{
|
|
||||||
this(bytes, 0, bytes.length, charsetName);
|
this(bytes, 0, bytes.length, charsetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,10 +535,7 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public String(byte bytes[], int offset, int length) {
|
public String(byte bytes[], int offset, int length) {
|
||||||
checkBounds(bytes, offset, length);
|
checkBounds(bytes, offset, length);
|
||||||
char[] v = StringCoding.decode(bytes, offset, length);
|
this.value = StringCoding.decode(bytes, offset, length);
|
||||||
this.offset = 0;
|
|
||||||
this.count = v.length;
|
|
||||||
this.value = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -612,10 +568,9 @@ public final class String
|
||||||
* A {@code StringBuffer}
|
* A {@code StringBuffer}
|
||||||
*/
|
*/
|
||||||
public String(StringBuffer buffer) {
|
public String(StringBuffer buffer) {
|
||||||
String result = buffer.toString();
|
synchronized(buffer) {
|
||||||
this.value = result.value;
|
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
|
||||||
this.count = result.count;
|
}
|
||||||
this.offset = result.offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -634,18 +589,18 @@ public final class String
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public String(StringBuilder builder) {
|
public String(StringBuilder builder) {
|
||||||
String result = builder.toString();
|
this.value = Arrays.copyOf(builder.getValue(), builder.length());
|
||||||
this.value = result.value;
|
|
||||||
this.count = result.count;
|
|
||||||
this.offset = result.offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Package private constructor which shares value array for speed.
|
* Package private constructor which shares value array for speed.
|
||||||
String(int offset, int count, char value[]) {
|
* this constructor is always expected to be called with share==true.
|
||||||
|
* a separate constructor is needed because we already have a public
|
||||||
|
* String(char[]) constructor that makes a copy of the given char[].
|
||||||
|
*/
|
||||||
|
String(char[] value, boolean share) {
|
||||||
|
// assert share : "unshared not supported";
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.offset = offset;
|
|
||||||
this.count = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -657,7 +612,7 @@ public final class String
|
||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
public int length() {
|
public int length() {
|
||||||
return count;
|
return value.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -669,7 +624,7 @@ public final class String
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return count == 0;
|
return value.length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -691,10 +646,10 @@ public final class String
|
||||||
* string.
|
* string.
|
||||||
*/
|
*/
|
||||||
public char charAt(int index) {
|
public char charAt(int index) {
|
||||||
if ((index < 0) || (index >= count)) {
|
if ((index < 0) || (index >= value.length)) {
|
||||||
throw new StringIndexOutOfBoundsException(index);
|
throw new StringIndexOutOfBoundsException(index);
|
||||||
}
|
}
|
||||||
return value[index + offset];
|
return value[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -720,10 +675,10 @@ public final class String
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public int codePointAt(int index) {
|
public int codePointAt(int index) {
|
||||||
if ((index < 0) || (index >= count)) {
|
if ((index < 0) || (index >= value.length)) {
|
||||||
throw new StringIndexOutOfBoundsException(index);
|
throw new StringIndexOutOfBoundsException(index);
|
||||||
}
|
}
|
||||||
return Character.codePointAtImpl(value, offset + index, offset + count);
|
return Character.codePointAtImpl(value, index, value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -750,10 +705,10 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public int codePointBefore(int index) {
|
public int codePointBefore(int index) {
|
||||||
int i = index - 1;
|
int i = index - 1;
|
||||||
if ((i < 0) || (i >= count)) {
|
if ((i < 0) || (i >= value.length)) {
|
||||||
throw new StringIndexOutOfBoundsException(index);
|
throw new StringIndexOutOfBoundsException(index);
|
||||||
}
|
}
|
||||||
return Character.codePointBeforeImpl(value, offset + index, offset);
|
return Character.codePointBeforeImpl(value, index, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -778,10 +733,10 @@ public final class String
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public int codePointCount(int beginIndex, int endIndex) {
|
public int codePointCount(int beginIndex, int endIndex) {
|
||||||
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
|
if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
return Character.codePointCountImpl(value, offset+beginIndex, endIndex-beginIndex);
|
return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -805,11 +760,11 @@ public final class String
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public int offsetByCodePoints(int index, int codePointOffset) {
|
public int offsetByCodePoints(int index, int codePointOffset) {
|
||||||
if (index < 0 || index > count) {
|
if (index < 0 || index > value.length) {
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
return Character.offsetByCodePointsImpl(value, offset, count,
|
return Character.offsetByCodePointsImpl(value, 0, value.length,
|
||||||
offset+index, codePointOffset) - offset;
|
index, codePointOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -817,7 +772,7 @@ public final class String
|
||||||
* This method doesn't perform any range checking.
|
* This method doesn't perform any range checking.
|
||||||
*/
|
*/
|
||||||
void getChars(char dst[], int dstBegin) {
|
void getChars(char dst[], int dstBegin) {
|
||||||
System.arraycopy(value, offset, dst, dstBegin, count);
|
System.arraycopy(value, 0, dst, dstBegin, value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -854,14 +809,13 @@ public final class String
|
||||||
if (srcBegin < 0) {
|
if (srcBegin < 0) {
|
||||||
throw new StringIndexOutOfBoundsException(srcBegin);
|
throw new StringIndexOutOfBoundsException(srcBegin);
|
||||||
}
|
}
|
||||||
if (srcEnd > count) {
|
if (srcEnd > value.length) {
|
||||||
throw new StringIndexOutOfBoundsException(srcEnd);
|
throw new StringIndexOutOfBoundsException(srcEnd);
|
||||||
}
|
}
|
||||||
if (srcBegin > srcEnd) {
|
if (srcBegin > srcEnd) {
|
||||||
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
|
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
|
||||||
}
|
}
|
||||||
System.arraycopy(value, offset + srcBegin, dst, dstBegin,
|
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
|
||||||
srcEnd - srcBegin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -912,15 +866,15 @@ public final class String
|
||||||
if (srcBegin < 0) {
|
if (srcBegin < 0) {
|
||||||
throw new StringIndexOutOfBoundsException(srcBegin);
|
throw new StringIndexOutOfBoundsException(srcBegin);
|
||||||
}
|
}
|
||||||
if (srcEnd > count) {
|
if (srcEnd > value.length) {
|
||||||
throw new StringIndexOutOfBoundsException(srcEnd);
|
throw new StringIndexOutOfBoundsException(srcEnd);
|
||||||
}
|
}
|
||||||
if (srcBegin > srcEnd) {
|
if (srcBegin > srcEnd) {
|
||||||
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
|
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
|
||||||
}
|
}
|
||||||
int j = dstBegin;
|
int j = dstBegin;
|
||||||
int n = offset + srcEnd;
|
int n = srcEnd;
|
||||||
int i = offset + srcBegin;
|
int i = srcBegin;
|
||||||
char[] val = value; /* avoid getfield opcode */
|
char[] val = value; /* avoid getfield opcode */
|
||||||
|
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
|
@ -949,10 +903,9 @@ public final class String
|
||||||
* @since JDK1.1
|
* @since JDK1.1
|
||||||
*/
|
*/
|
||||||
public byte[] getBytes(String charsetName)
|
public byte[] getBytes(String charsetName)
|
||||||
throws UnsupportedEncodingException
|
throws UnsupportedEncodingException {
|
||||||
{
|
|
||||||
if (charsetName == null) throw new NullPointerException();
|
if (charsetName == null) throw new NullPointerException();
|
||||||
return StringCoding.encode(charsetName, value, offset, count);
|
return StringCoding.encode(charsetName, value, 0, value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -975,7 +928,7 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public byte[] getBytes(Charset charset) {
|
public byte[] getBytes(Charset charset) {
|
||||||
if (charset == null) throw new NullPointerException();
|
if (charset == null) throw new NullPointerException();
|
||||||
return StringCoding.encode(charset, value, offset, count);
|
return StringCoding.encode(charset, value, 0, value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -992,7 +945,7 @@ public final class String
|
||||||
* @since JDK1.1
|
* @since JDK1.1
|
||||||
*/
|
*/
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
return StringCoding.encode(value, offset, count);
|
return StringCoding.encode(value, 0, value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1016,15 +969,15 @@ public final class String
|
||||||
}
|
}
|
||||||
if (anObject instanceof String) {
|
if (anObject instanceof String) {
|
||||||
String anotherString = (String) anObject;
|
String anotherString = (String) anObject;
|
||||||
int n = count;
|
int n = value.length;
|
||||||
if (n == anotherString.count) {
|
if (n == anotherString.value.length) {
|
||||||
char v1[] = value;
|
char v1[] = value;
|
||||||
char v2[] = anotherString.value;
|
char v2[] = anotherString.value;
|
||||||
int i = offset;
|
int i = 0;
|
||||||
int j = anotherString.offset;
|
|
||||||
while (n-- != 0) {
|
while (n-- != 0) {
|
||||||
if (v1[i++] != v2[j++])
|
if (v1[i] != v2[i])
|
||||||
return false;
|
return false;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1067,18 +1020,18 @@ public final class String
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public boolean contentEquals(CharSequence cs) {
|
public boolean contentEquals(CharSequence cs) {
|
||||||
if (count != cs.length())
|
if (value.length != cs.length())
|
||||||
return false;
|
return false;
|
||||||
// Argument is a StringBuffer, StringBuilder
|
// Argument is a StringBuffer, StringBuilder
|
||||||
if (cs instanceof AbstractStringBuilder) {
|
if (cs instanceof AbstractStringBuilder) {
|
||||||
char v1[] = value;
|
char v1[] = value;
|
||||||
char v2[] = ((AbstractStringBuilder) cs).getValue();
|
char v2[] = ((AbstractStringBuilder) cs).getValue();
|
||||||
int i = offset;
|
int i = 0;
|
||||||
int j = 0;
|
int n = value.length;
|
||||||
int n = count;
|
|
||||||
while (n-- != 0) {
|
while (n-- != 0) {
|
||||||
if (v1[i++] != v2[j++])
|
if (v1[i] != v2[i])
|
||||||
return false;
|
return false;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1087,12 +1040,12 @@ public final class String
|
||||||
return true;
|
return true;
|
||||||
// Argument is a generic CharSequence
|
// Argument is a generic CharSequence
|
||||||
char v1[] = value;
|
char v1[] = value;
|
||||||
int i = offset;
|
int i = 0;
|
||||||
int j = 0;
|
int n = value.length;
|
||||||
int n = count;
|
|
||||||
while (n-- != 0) {
|
while (n-- != 0) {
|
||||||
if (v1[i++] != cs.charAt(j++))
|
if (v1[i] != cs.charAt(i))
|
||||||
return false;
|
return false;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1126,9 +1079,10 @@ public final class String
|
||||||
* @see #equals(Object)
|
* @see #equals(Object)
|
||||||
*/
|
*/
|
||||||
public boolean equalsIgnoreCase(String anotherString) {
|
public boolean equalsIgnoreCase(String anotherString) {
|
||||||
return (this == anotherString) ? true :
|
return (this == anotherString) ? true
|
||||||
(anotherString != null) && (anotherString.count == count) &&
|
: (anotherString != null)
|
||||||
regionMatches(true, 0, anotherString, 0, count);
|
&& (anotherString.value.length == value.length)
|
||||||
|
&& regionMatches(true, 0, anotherString, 0, value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1173,17 +1127,13 @@ public final class String
|
||||||
* lexicographically greater than the string argument.
|
* lexicographically greater than the string argument.
|
||||||
*/
|
*/
|
||||||
public int compareTo(String anotherString) {
|
public int compareTo(String anotherString) {
|
||||||
int len1 = count;
|
int len1 = value.length;
|
||||||
int len2 = anotherString.count;
|
int len2 = anotherString.value.length;
|
||||||
int n = Math.min(len1, len2);
|
int lim = Math.min(len1, len2);
|
||||||
char v1[] = value;
|
char v1[] = value;
|
||||||
char v2[] = anotherString.value;
|
char v2[] = anotherString.value;
|
||||||
int i = offset;
|
|
||||||
int j = anotherString.offset;
|
|
||||||
|
|
||||||
if (i == j) {
|
int k = 0;
|
||||||
int k = i;
|
|
||||||
int lim = n + i;
|
|
||||||
while (k < lim) {
|
while (k < lim) {
|
||||||
char c1 = v1[k];
|
char c1 = v1[k];
|
||||||
char c2 = v2[k];
|
char c2 = v2[k];
|
||||||
|
@ -1192,15 +1142,6 @@ public final class String
|
||||||
}
|
}
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
while (n-- != 0) {
|
|
||||||
char c1 = v1[i++];
|
|
||||||
char c2 = v2[j++];
|
|
||||||
if (c1 != c2) {
|
|
||||||
return c1 - c2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len1 - len2;
|
return len1 - len2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1308,12 +1249,13 @@ public final class String
|
||||||
public boolean regionMatches(int toffset, String other, int ooffset,
|
public boolean regionMatches(int toffset, String other, int ooffset,
|
||||||
int len) {
|
int len) {
|
||||||
char ta[] = value;
|
char ta[] = value;
|
||||||
int to = offset + toffset;
|
int to = toffset;
|
||||||
char pa[] = other.value;
|
char pa[] = other.value;
|
||||||
int po = other.offset + ooffset;
|
int po = ooffset;
|
||||||
// Note: toffset, ooffset, or len might be near -1>>>1.
|
// Note: toffset, ooffset, or len might be near -1>>>1.
|
||||||
if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len)
|
if ((ooffset < 0) || (toffset < 0)
|
||||||
|| (ooffset > (long)other.count - len)) {
|
|| (toffset > (long)value.length - len)
|
||||||
|
|| (ooffset > (long)other.value.length - len)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
|
@ -1377,12 +1319,13 @@ public final class String
|
||||||
public boolean regionMatches(boolean ignoreCase, int toffset,
|
public boolean regionMatches(boolean ignoreCase, int toffset,
|
||||||
String other, int ooffset, int len) {
|
String other, int ooffset, int len) {
|
||||||
char ta[] = value;
|
char ta[] = value;
|
||||||
int to = offset + toffset;
|
int to = toffset;
|
||||||
char pa[] = other.value;
|
char pa[] = other.value;
|
||||||
int po = other.offset + ooffset;
|
int po = ooffset;
|
||||||
// Note: toffset, ooffset, or len might be near -1>>>1.
|
// Note: toffset, ooffset, or len might be near -1>>>1.
|
||||||
if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len) ||
|
if ((ooffset < 0) || (toffset < 0)
|
||||||
(ooffset > (long)other.count - len)) {
|
|| (toffset > (long)value.length - len)
|
||||||
|
|| (ooffset > (long)other.value.length - len)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
|
@ -1433,12 +1376,12 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public boolean startsWith(String prefix, int toffset) {
|
public boolean startsWith(String prefix, int toffset) {
|
||||||
char ta[] = value;
|
char ta[] = value;
|
||||||
int to = offset + toffset;
|
int to = toffset;
|
||||||
char pa[] = prefix.value;
|
char pa[] = prefix.value;
|
||||||
int po = prefix.offset;
|
int po = 0;
|
||||||
int pc = prefix.count;
|
int pc = prefix.value.length;
|
||||||
// Note: toffset might be near -1>>>1.
|
// Note: toffset might be near -1>>>1.
|
||||||
if ((toffset < 0) || (toffset > count - pc)) {
|
if ((toffset < 0) || (toffset > value.length - pc)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (--pc >= 0) {
|
while (--pc >= 0) {
|
||||||
|
@ -1478,7 +1421,7 @@ public final class String
|
||||||
* as determined by the {@link #equals(Object)} method.
|
* as determined by the {@link #equals(Object)} method.
|
||||||
*/
|
*/
|
||||||
public boolean endsWith(String suffix) {
|
public boolean endsWith(String suffix) {
|
||||||
return startsWith(suffix, count - suffix.count);
|
return startsWith(suffix, value.length - suffix.value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1496,13 +1439,11 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int h = hash;
|
int h = hash;
|
||||||
if (h == 0 && count > 0) {
|
if (h == 0 && value.length > 0) {
|
||||||
int off = offset;
|
|
||||||
char val[] = value;
|
char val[] = value;
|
||||||
int len = count;
|
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
h = 31*h + val[off++];
|
h = 31 * h + val[i];
|
||||||
}
|
}
|
||||||
hash = h;
|
hash = h;
|
||||||
}
|
}
|
||||||
|
@ -1577,9 +1518,10 @@ public final class String
|
||||||
* if the character does not occur.
|
* if the character does not occur.
|
||||||
*/
|
*/
|
||||||
public int indexOf(int ch, int fromIndex) {
|
public int indexOf(int ch, int fromIndex) {
|
||||||
|
final int max = value.length;
|
||||||
if (fromIndex < 0) {
|
if (fromIndex < 0) {
|
||||||
fromIndex = 0;
|
fromIndex = 0;
|
||||||
} else if (fromIndex >= count) {
|
} else if (fromIndex >= max) {
|
||||||
// Note: fromIndex might be near -1>>>1.
|
// Note: fromIndex might be near -1>>>1.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1588,11 +1530,9 @@ public final class String
|
||||||
// handle most cases here (ch is a BMP code point or a
|
// handle most cases here (ch is a BMP code point or a
|
||||||
// negative value (invalid code point))
|
// negative value (invalid code point))
|
||||||
final char[] value = this.value;
|
final char[] value = this.value;
|
||||||
final int offset = this.offset;
|
for (int i = fromIndex; i < max; i++) {
|
||||||
final int max = offset + count;
|
|
||||||
for (int i = offset + fromIndex; i < max ; i++) {
|
|
||||||
if (value[i] == ch) {
|
if (value[i] == ch) {
|
||||||
return i - offset;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1607,13 +1547,12 @@ public final class String
|
||||||
private int indexOfSupplementary(int ch, int fromIndex) {
|
private int indexOfSupplementary(int ch, int fromIndex) {
|
||||||
if (Character.isValidCodePoint(ch)) {
|
if (Character.isValidCodePoint(ch)) {
|
||||||
final char[] value = this.value;
|
final char[] value = this.value;
|
||||||
final int offset = this.offset;
|
|
||||||
final char hi = Character.highSurrogate(ch);
|
final char hi = Character.highSurrogate(ch);
|
||||||
final char lo = Character.lowSurrogate(ch);
|
final char lo = Character.lowSurrogate(ch);
|
||||||
final int max = offset + count - 1;
|
final int max = value.length - 1;
|
||||||
for (int i = offset + fromIndex; i < max; i++) {
|
for (int i = fromIndex; i < max; i++) {
|
||||||
if (value[i] == hi && value[i + 1] == lo) {
|
if (value[i] == hi && value[i + 1] == lo) {
|
||||||
return i - offset;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1644,7 +1583,7 @@ public final class String
|
||||||
* {@code -1} if the character does not occur.
|
* {@code -1} if the character does not occur.
|
||||||
*/
|
*/
|
||||||
public int lastIndexOf(int ch) {
|
public int lastIndexOf(int ch) {
|
||||||
return lastIndexOf(ch, count - 1);
|
return lastIndexOf(ch, value.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1686,11 +1625,10 @@ public final class String
|
||||||
// handle most cases here (ch is a BMP code point or a
|
// handle most cases here (ch is a BMP code point or a
|
||||||
// negative value (invalid code point))
|
// negative value (invalid code point))
|
||||||
final char[] value = this.value;
|
final char[] value = this.value;
|
||||||
final int offset = this.offset;
|
int i = Math.min(fromIndex, value.length - 1);
|
||||||
int i = offset + Math.min(fromIndex, count - 1);
|
for (; i >= 0; i--) {
|
||||||
for (; i >= offset ; i--) {
|
|
||||||
if (value[i] == ch) {
|
if (value[i] == ch) {
|
||||||
return i - offset;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1705,13 +1643,12 @@ public final class String
|
||||||
private int lastIndexOfSupplementary(int ch, int fromIndex) {
|
private int lastIndexOfSupplementary(int ch, int fromIndex) {
|
||||||
if (Character.isValidCodePoint(ch)) {
|
if (Character.isValidCodePoint(ch)) {
|
||||||
final char[] value = this.value;
|
final char[] value = this.value;
|
||||||
final int offset = this.offset;
|
|
||||||
char hi = Character.highSurrogate(ch);
|
char hi = Character.highSurrogate(ch);
|
||||||
char lo = Character.lowSurrogate(ch);
|
char lo = Character.lowSurrogate(ch);
|
||||||
int i = offset + Math.min(fromIndex, count - 2);
|
int i = Math.min(fromIndex, value.length - 2);
|
||||||
for (; i >= offset; i--) {
|
for (; i >= 0; i--) {
|
||||||
if (value[i] == hi && value[i + 1] == lo) {
|
if (value[i] == hi && value[i + 1] == lo) {
|
||||||
return i - offset;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1753,8 +1690,8 @@ public final class String
|
||||||
* or {@code -1} if there is no such occurrence.
|
* or {@code -1} if there is no such occurrence.
|
||||||
*/
|
*/
|
||||||
public int indexOf(String str, int fromIndex) {
|
public int indexOf(String str, int fromIndex) {
|
||||||
return indexOf(value, offset, count,
|
return indexOf(value, 0, value.length,
|
||||||
str.value, str.offset, str.count, fromIndex);
|
str.value, 0, str.value.length, fromIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1796,8 +1733,8 @@ public final class String
|
||||||
if (i <= max) {
|
if (i <= max) {
|
||||||
int j = i + 1;
|
int j = i + 1;
|
||||||
int end = j + targetCount - 1;
|
int end = j + targetCount - 1;
|
||||||
for (int k = targetOffset + 1; j < end && source[j] ==
|
for (int k = targetOffset + 1; j < end && source[j]
|
||||||
target[k]; j++, k++);
|
== target[k]; j++, k++);
|
||||||
|
|
||||||
if (j == end) {
|
if (j == end) {
|
||||||
/* Found whole string. */
|
/* Found whole string. */
|
||||||
|
@ -1824,7 +1761,7 @@ public final class String
|
||||||
* or {@code -1} if there is no such occurrence.
|
* or {@code -1} if there is no such occurrence.
|
||||||
*/
|
*/
|
||||||
public int lastIndexOf(String str) {
|
public int lastIndexOf(String str) {
|
||||||
return lastIndexOf(str, count);
|
return lastIndexOf(str, value.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1844,8 +1781,8 @@ public final class String
|
||||||
* or {@code -1} if there is no such occurrence.
|
* or {@code -1} if there is no such occurrence.
|
||||||
*/
|
*/
|
||||||
public int lastIndexOf(String str, int fromIndex) {
|
public int lastIndexOf(String str, int fromIndex) {
|
||||||
return lastIndexOf(value, offset, count,
|
return lastIndexOf(value, 0, value.length,
|
||||||
str.value, str.offset, str.count, fromIndex);
|
str.value, 0, str.value.length, fromIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1925,7 +1862,14 @@ public final class String
|
||||||
* length of this {@code String} object.
|
* length of this {@code String} object.
|
||||||
*/
|
*/
|
||||||
public String substring(int beginIndex) {
|
public String substring(int beginIndex) {
|
||||||
return substring(beginIndex, count);
|
if (beginIndex < 0) {
|
||||||
|
throw new StringIndexOutOfBoundsException(beginIndex);
|
||||||
|
}
|
||||||
|
int subLen = value.length - beginIndex;
|
||||||
|
if (subLen < 0) {
|
||||||
|
throw new StringIndexOutOfBoundsException(subLen);
|
||||||
|
}
|
||||||
|
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1954,14 +1898,15 @@ public final class String
|
||||||
if (beginIndex < 0) {
|
if (beginIndex < 0) {
|
||||||
throw new StringIndexOutOfBoundsException(beginIndex);
|
throw new StringIndexOutOfBoundsException(beginIndex);
|
||||||
}
|
}
|
||||||
if (endIndex > count) {
|
if (endIndex > value.length) {
|
||||||
throw new StringIndexOutOfBoundsException(endIndex);
|
throw new StringIndexOutOfBoundsException(endIndex);
|
||||||
}
|
}
|
||||||
if (beginIndex > endIndex) {
|
int subLen = endIndex - beginIndex;
|
||||||
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
|
if (subLen < 0) {
|
||||||
|
throw new StringIndexOutOfBoundsException(subLen);
|
||||||
}
|
}
|
||||||
return ((beginIndex == 0) && (endIndex == count)) ? this :
|
return ((beginIndex == 0) && (endIndex == value.length)) ? this
|
||||||
new String(offset + beginIndex, endIndex - beginIndex, value);
|
: new String(value, beginIndex, subLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2021,10 +1966,10 @@ public final class String
|
||||||
if (otherLen == 0) {
|
if (otherLen == 0) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
char buf[] = new char[count + otherLen];
|
int len = value.length;
|
||||||
getChars(0, count, buf, 0);
|
char buf[] = Arrays.copyOf(value, len + otherLen);
|
||||||
str.getChars(0, otherLen, buf, count);
|
str.getChars(buf, len);
|
||||||
return new String(0, count + otherLen, buf);
|
return new String(buf, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2058,27 +2003,26 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public String replace(char oldChar, char newChar) {
|
public String replace(char oldChar, char newChar) {
|
||||||
if (oldChar != newChar) {
|
if (oldChar != newChar) {
|
||||||
int len = count;
|
int len = value.length;
|
||||||
int i = -1;
|
int i = -1;
|
||||||
char[] val = value; /* avoid getfield opcode */
|
char[] val = value; /* avoid getfield opcode */
|
||||||
int off = offset; /* avoid getfield opcode */
|
|
||||||
|
|
||||||
while (++i < len) {
|
while (++i < len) {
|
||||||
if (val[off + i] == oldChar) {
|
if (val[i] == oldChar) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < len) {
|
if (i < len) {
|
||||||
char buf[] = new char[len];
|
char buf[] = new char[len];
|
||||||
for (int j = 0; j < i; j++) {
|
for (int j = 0; j < i; j++) {
|
||||||
buf[j] = val[off+j];
|
buf[j] = val[j];
|
||||||
}
|
}
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
char c = val[off + i];
|
char c = val[i];
|
||||||
buf[i] = (c == oldChar) ? newChar : c;
|
buf[i] = (c == oldChar) ? newChar : c;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return new String(0, len, buf);
|
return new String(buf, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -2320,7 +2264,7 @@ public final class String
|
||||||
the second is not the ascii digit or ascii letter.
|
the second is not the ascii digit or ascii letter.
|
||||||
*/
|
*/
|
||||||
char ch = 0;
|
char ch = 0;
|
||||||
if (((regex.count == 1 &&
|
if (((regex.value.length == 1 &&
|
||||||
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
|
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
|
||||||
(regex.length() == 2 &&
|
(regex.length() == 2 &&
|
||||||
regex.charAt(0) == '\\' &&
|
regex.charAt(0) == '\\' &&
|
||||||
|
@ -2340,8 +2284,8 @@ public final class String
|
||||||
off = next + 1;
|
off = next + 1;
|
||||||
} else { // last one
|
} else { // last one
|
||||||
//assert (list.size() == limit - 1);
|
//assert (list.size() == limit - 1);
|
||||||
list.add(substring(off, count));
|
list.add(substring(off, value.length));
|
||||||
off = count;
|
off = value.length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2351,7 +2295,7 @@ public final class String
|
||||||
|
|
||||||
// Add remaining segment
|
// Add remaining segment
|
||||||
if (!limited || list.size() < limit)
|
if (!limited || list.size() < limit)
|
||||||
list.add(substring(off, count));
|
list.add(substring(off, value.length));
|
||||||
|
|
||||||
// Construct result
|
// Construct result
|
||||||
int resultSize = list.size();
|
int resultSize = list.size();
|
||||||
|
@ -2464,13 +2408,14 @@ public final class String
|
||||||
}
|
}
|
||||||
|
|
||||||
int firstUpper;
|
int firstUpper;
|
||||||
|
final int len = value.length;
|
||||||
|
|
||||||
/* Now check if there are any characters that need to be changed. */
|
/* Now check if there are any characters that need to be changed. */
|
||||||
scan: {
|
scan: {
|
||||||
for (firstUpper = 0 ; firstUpper < count; ) {
|
for (firstUpper = 0 ; firstUpper < len; ) {
|
||||||
char c = value[offset+firstUpper];
|
char c = value[firstUpper];
|
||||||
if ((c >= Character.MIN_HIGH_SURROGATE) &&
|
if ((c >= Character.MIN_HIGH_SURROGATE)
|
||||||
(c <= Character.MAX_HIGH_SURROGATE)) {
|
&& (c <= Character.MAX_HIGH_SURROGATE)) {
|
||||||
int supplChar = codePointAt(firstUpper);
|
int supplChar = codePointAt(firstUpper);
|
||||||
if (supplChar != Character.toLowerCase(supplChar)) {
|
if (supplChar != Character.toLowerCase(supplChar)) {
|
||||||
break scan;
|
break scan;
|
||||||
|
@ -2486,12 +2431,12 @@ public final class String
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
char[] result = new char[count];
|
char[] result = new char[len];
|
||||||
int resultOffset = 0; /* result may grow, so i+resultOffset
|
int resultOffset = 0; /* result may grow, so i+resultOffset
|
||||||
* is the write location in result */
|
* is the write location in result */
|
||||||
|
|
||||||
/* Just copy the first few lowerCase characters. */
|
/* Just copy the first few lowerCase characters. */
|
||||||
System.arraycopy(value, offset, result, 0, firstUpper);
|
System.arraycopy(value, 0, result, 0, firstUpper);
|
||||||
|
|
||||||
String lang = locale.getLanguage();
|
String lang = locale.getLanguage();
|
||||||
boolean localeDependent =
|
boolean localeDependent =
|
||||||
|
@ -2500,10 +2445,10 @@ public final class String
|
||||||
int lowerChar;
|
int lowerChar;
|
||||||
int srcChar;
|
int srcChar;
|
||||||
int srcCount;
|
int srcCount;
|
||||||
for (int i = firstUpper; i < count; i += srcCount) {
|
for (int i = firstUpper; i < len; i += srcCount) {
|
||||||
srcChar = (int)value[offset+i];
|
srcChar = (int)value[i];
|
||||||
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
|
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE
|
||||||
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
|
&& (char)srcChar <= Character.MAX_HIGH_SURROGATE) {
|
||||||
srcChar = codePointAt(i);
|
srcChar = codePointAt(i);
|
||||||
srcCount = Character.charCount(srcChar);
|
srcCount = Character.charCount(srcChar);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2516,8 +2461,8 @@ public final class String
|
||||||
} else {
|
} else {
|
||||||
lowerChar = Character.toLowerCase(srcChar);
|
lowerChar = Character.toLowerCase(srcChar);
|
||||||
}
|
}
|
||||||
if ((lowerChar == Character.ERROR) ||
|
if ((lowerChar == Character.ERROR)
|
||||||
(lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
|
|| (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
|
||||||
if (lowerChar == Character.ERROR) {
|
if (lowerChar == Character.ERROR) {
|
||||||
if (!localeDependent && srcChar == '\u0130') {
|
if (!localeDependent && srcChar == '\u0130') {
|
||||||
lowerCharArray =
|
lowerCharArray =
|
||||||
|
@ -2537,8 +2482,7 @@ public final class String
|
||||||
int mapLen = lowerCharArray.length;
|
int mapLen = lowerCharArray.length;
|
||||||
if (mapLen > srcCount) {
|
if (mapLen > srcCount) {
|
||||||
char[] result2 = new char[result.length + mapLen - srcCount];
|
char[] result2 = new char[result.length + mapLen - srcCount];
|
||||||
System.arraycopy(result, 0, result2, 0,
|
System.arraycopy(result, 0, result2, 0, i + resultOffset);
|
||||||
i + resultOffset);
|
|
||||||
result = result2;
|
result = result2;
|
||||||
}
|
}
|
||||||
for (int x = 0; x < mapLen; ++x) {
|
for (int x = 0; x < mapLen; ++x) {
|
||||||
|
@ -2549,7 +2493,7 @@ public final class String
|
||||||
result[i + resultOffset] = (char)lowerChar;
|
result[i + resultOffset] = (char)lowerChar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new String(0, count+resultOffset, result);
|
return new String(result, 0, len + resultOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2629,22 +2573,23 @@ public final class String
|
||||||
}
|
}
|
||||||
|
|
||||||
int firstLower;
|
int firstLower;
|
||||||
|
final int len = value.length;
|
||||||
|
|
||||||
/* Now check if there are any characters that need to be changed. */
|
/* Now check if there are any characters that need to be changed. */
|
||||||
scan: {
|
scan: {
|
||||||
for (firstLower = 0 ; firstLower < count; ) {
|
for (firstLower = 0 ; firstLower < len; ) {
|
||||||
int c = (int)value[offset+firstLower];
|
int c = (int)value[firstLower];
|
||||||
int srcCount;
|
int srcCount;
|
||||||
if ((c >= Character.MIN_HIGH_SURROGATE) &&
|
if ((c >= Character.MIN_HIGH_SURROGATE)
|
||||||
(c <= Character.MAX_HIGH_SURROGATE)) {
|
&& (c <= Character.MAX_HIGH_SURROGATE)) {
|
||||||
c = codePointAt(firstLower);
|
c = codePointAt(firstLower);
|
||||||
srcCount = Character.charCount(c);
|
srcCount = Character.charCount(c);
|
||||||
} else {
|
} else {
|
||||||
srcCount = 1;
|
srcCount = 1;
|
||||||
}
|
}
|
||||||
int upperCaseChar = Character.toUpperCaseEx(c);
|
int upperCaseChar = Character.toUpperCaseEx(c);
|
||||||
if ((upperCaseChar == Character.ERROR) ||
|
if ((upperCaseChar == Character.ERROR)
|
||||||
(c != upperCaseChar)) {
|
|| (c != upperCaseChar)) {
|
||||||
break scan;
|
break scan;
|
||||||
}
|
}
|
||||||
firstLower += srcCount;
|
firstLower += srcCount;
|
||||||
|
@ -2652,12 +2597,12 @@ public final class String
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
char[] result = new char[count]; /* may grow */
|
char[] result = new char[len]; /* may grow */
|
||||||
int resultOffset = 0; /* result may grow, so i+resultOffset
|
int resultOffset = 0; /* result may grow, so i+resultOffset
|
||||||
* is the write location in result */
|
* is the write location in result */
|
||||||
|
|
||||||
/* Just copy the first few upperCase characters. */
|
/* Just copy the first few upperCase characters. */
|
||||||
System.arraycopy(value, offset, result, 0, firstLower);
|
System.arraycopy(value, 0, result, 0, firstLower);
|
||||||
|
|
||||||
String lang = locale.getLanguage();
|
String lang = locale.getLanguage();
|
||||||
boolean localeDependent =
|
boolean localeDependent =
|
||||||
|
@ -2666,8 +2611,8 @@ public final class String
|
||||||
int upperChar;
|
int upperChar;
|
||||||
int srcChar;
|
int srcChar;
|
||||||
int srcCount;
|
int srcCount;
|
||||||
for (int i = firstLower; i < count; i += srcCount) {
|
for (int i = firstLower; i < len; i += srcCount) {
|
||||||
srcChar = (int)value[offset+i];
|
srcChar = (int)value[i];
|
||||||
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
|
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
|
||||||
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
|
(char)srcChar <= Character.MAX_HIGH_SURROGATE) {
|
||||||
srcChar = codePointAt(i);
|
srcChar = codePointAt(i);
|
||||||
|
@ -2680,8 +2625,8 @@ public final class String
|
||||||
} else {
|
} else {
|
||||||
upperChar = Character.toUpperCaseEx(srcChar);
|
upperChar = Character.toUpperCaseEx(srcChar);
|
||||||
}
|
}
|
||||||
if ((upperChar == Character.ERROR) ||
|
if ((upperChar == Character.ERROR)
|
||||||
(upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
|
|| (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
|
||||||
if (upperChar == Character.ERROR) {
|
if (upperChar == Character.ERROR) {
|
||||||
if (localeDependent) {
|
if (localeDependent) {
|
||||||
upperCharArray =
|
upperCharArray =
|
||||||
|
@ -2700,8 +2645,7 @@ public final class String
|
||||||
int mapLen = upperCharArray.length;
|
int mapLen = upperCharArray.length;
|
||||||
if (mapLen > srcCount) {
|
if (mapLen > srcCount) {
|
||||||
char[] result2 = new char[result.length + mapLen - srcCount];
|
char[] result2 = new char[result.length + mapLen - srcCount];
|
||||||
System.arraycopy(result, 0, result2, 0,
|
System.arraycopy(result, 0, result2, 0, i + resultOffset);
|
||||||
i + resultOffset);
|
|
||||||
result = result2;
|
result = result2;
|
||||||
}
|
}
|
||||||
for (int x = 0; x < mapLen; ++x) {
|
for (int x = 0; x < mapLen; ++x) {
|
||||||
|
@ -2712,7 +2656,7 @@ public final class String
|
||||||
result[i + resultOffset] = (char)upperChar;
|
result[i + resultOffset] = (char)upperChar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new String(0, count+resultOffset, result);
|
return new String(result, 0, len + resultOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2770,18 +2714,17 @@ public final class String
|
||||||
* trailing white space.
|
* trailing white space.
|
||||||
*/
|
*/
|
||||||
public String trim() {
|
public String trim() {
|
||||||
int len = count;
|
int len = value.length;
|
||||||
int st = 0;
|
int st = 0;
|
||||||
int off = offset; /* avoid getfield opcode */
|
|
||||||
char[] val = value; /* avoid getfield opcode */
|
char[] val = value; /* avoid getfield opcode */
|
||||||
|
|
||||||
while ((st < len) && (val[off + st] <= ' ')) {
|
while ((st < len) && (val[st] <= ' ')) {
|
||||||
st++;
|
st++;
|
||||||
}
|
}
|
||||||
while ((st < len) && (val[off + len - 1] <= ' ')) {
|
while ((st < len) && (val[len - 1] <= ' ')) {
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
return ((st > 0) || (len < count)) ? substring(st, len) : this;
|
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2801,8 +2744,9 @@ public final class String
|
||||||
* the character sequence represented by this string.
|
* the character sequence represented by this string.
|
||||||
*/
|
*/
|
||||||
public char[] toCharArray() {
|
public char[] toCharArray() {
|
||||||
char result[] = new char[count];
|
// Cannot use Arrays.copyOf because of class initialization order issues
|
||||||
getChars(0, count, result, 0);
|
char result[] = new char[value.length];
|
||||||
|
System.arraycopy(value, 0, result, 0, value.length);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2968,7 +2912,7 @@ public final class String
|
||||||
* character array.
|
* character array.
|
||||||
*/
|
*/
|
||||||
public static String copyValueOf(char data[]) {
|
public static String copyValueOf(char data[]) {
|
||||||
return copyValueOf(data, 0, data.length);
|
return new String(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2993,7 +2937,7 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public static String valueOf(char c) {
|
public static String valueOf(char c) {
|
||||||
char data[] = {c};
|
char data[] = {c};
|
||||||
return new String(0, 1, data);
|
return new String(data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -250,6 +250,7 @@ class StringCoding {
|
||||||
static char[] decode(byte[] ba, int off, int len) {
|
static char[] decode(byte[] ba, int off, int len) {
|
||||||
String csn = Charset.defaultCharset().name();
|
String csn = Charset.defaultCharset().name();
|
||||||
try {
|
try {
|
||||||
|
// use charset name decode() variant which provides caching.
|
||||||
return decode(csn, ba, off, len);
|
return decode(csn, ba, off, len);
|
||||||
} catch (UnsupportedEncodingException x) {
|
} catch (UnsupportedEncodingException x) {
|
||||||
warnUnsupportedCharset(csn);
|
warnUnsupportedCharset(csn);
|
||||||
|
@ -382,6 +383,7 @@ class StringCoding {
|
||||||
static byte[] encode(char[] ca, int off, int len) {
|
static byte[] encode(char[] ca, int off, int len) {
|
||||||
String csn = Charset.defaultCharset().name();
|
String csn = Charset.defaultCharset().name();
|
||||||
try {
|
try {
|
||||||
|
// use charset name encode() variant which provides caching.
|
||||||
return encode(csn, ca, off, len);
|
return encode(csn, ca, off, len);
|
||||||
} catch (UnsupportedEncodingException x) {
|
} catch (UnsupportedEncodingException x) {
|
||||||
warnUnsupportedCharset(csn);
|
warnUnsupportedCharset(csn);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue