< prev index next >
src/java.base/share/classes/java/lang/AbstractStringBuilder.java
Print this page
*** 68,77 ****
--- 68,82 ----
* The count is the number of characters used.
*/
int count;
/**
+ * Whether value array is shared with a String.
+ */
+ transient boolean shared;
+
+ /**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
}
*** 86,95 ****
--- 91,109 ----
value = StringUTF16.newBytesFor(capacity);
coder = UTF16;
}
}
+ byte[] unshareValue() {
+ if (shared) {
+ // assert (count << coder) == value.length
+ value = Arrays.copyOf(value, value.length);
+ shared = false;
+ }
+ return value;
+ }
+
/**
* Returns the length (character count).
*
* @return the length of the sequence of characters currently
* represented by this object
*** 164,173 ****
--- 178,188 ----
throw new OutOfMemoryError();
}
newCapacity = StringUTF16.MAX_LENGTH;
}
this.value = Arrays.copyOf(value, newCapacity << coder);
+ this.shared = false;
}
/**
* If the coder is "isLatin1", this inflates the internal 8-bit storage
* to 16-bit <hi=0, low> pair storage.
*** 178,187 ****
--- 193,203 ----
}
byte[] buf = StringUTF16.newBytesFor(value.length);
StringLatin1.inflateSB(value, buf, 0, count);
this.value = buf;
this.coder = UTF16;
+ this.shared = false;
}
/**
* Attempts to reduce storage used for the character sequence.
* If the buffer is larger than necessary to hold its current sequence of
*** 223,239 ****
*/
public void setLength(int newLength) {
if (newLength < 0) {
throw new StringIndexOutOfBoundsException(newLength);
}
- ensureCapacityInternal(newLength);
if (count < newLength) {
if (isLatin1()) {
StringLatin1.fillNull(value, count, newLength);
} else {
StringUTF16.fillNull(value, count, newLength);
}
}
count = newLength;
}
/**
--- 239,257 ----
*/
public void setLength(int newLength) {
if (newLength < 0) {
throw new StringIndexOutOfBoundsException(newLength);
}
if (count < newLength) {
+ ensureCapacityInternal(newLength);
if (isLatin1()) {
StringLatin1.fillNull(value, count, newLength);
} else {
StringUTF16.fillNull(value, count, newLength);
}
+ } else if (newLength < count) {
+ unshareValue();
}
count = newLength;
}
/**
*** 435,448 ****
--- 453,469 ----
* negative or greater than or equal to {@code length()}.
*/
public void setCharAt(int index, char ch) {
checkIndex(index, count);
if (isLatin1() && StringLatin1.canEncode(ch)) {
+ final byte[] value = unshareValue();
value[index] = (byte)ch;
} else {
if (isLatin1()) {
inflate();
+ } else {
+ unshareValue();
}
StringUTF16.putCharSB(value, index, ch);
}
}
*** 824,833 ****
--- 845,855 ----
end = count;
}
checkRangeSIOOBE(start, end, count);
int len = end - start;
if (len > 0) {
+ unshareValue();
shift(end, -len);
count -= len;
}
return this;
}
*** 875,884 ****
--- 897,907 ----
* is negative or greater than or equal to
* {@code length()}.
*/
public AbstractStringBuilder deleteCharAt(int index) {
checkIndex(index, count);
+ unshareValue();
shift(index + 1, -1);
count--;
return this;
}
*** 907,916 ****
--- 930,940 ----
}
checkRangeSIOOBE(start, end, count);
int len = str.length();
int newCount = count + len - (end - start);
ensureCapacityInternal(newCount);
+ unshareValue();
shift(end, newCount - count);
count = newCount;
putStringAt(start, str);
return this;
}
*** 1463,1473 ****
* a valid surrogate pair.
*
* @return a reference to this object.
*/
public AbstractStringBuilder reverse() {
! byte[] val = this.value;
int count = this.count;
int coder = this.coder;
int n = count - 1;
if (COMPACT_STRINGS && coder == LATIN1) {
for (int j = (n-1) >> 1; j >= 0; j--) {
--- 1487,1497 ----
* a valid surrogate pair.
*
* @return a reference to this object.
*/
public AbstractStringBuilder reverse() {
! byte[] val = unshareValue();
int count = this.count;
int coder = this.coder;
int n = count - 1;
if (COMPACT_STRINGS && coder == LATIN1) {
for (int j = (n-1) >> 1; j >= 0; j--) {
*** 1573,1583 ****
* @param coder the coder of dst[]
*/
void getBytes(byte dst[], int dstBegin, byte coder) {
if (this.coder == coder) {
System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
! } else { // this.coder == LATIN && coder == UTF16
StringLatin1.inflateSB(value, dst, dstBegin, count);
}
}
/* for readObject() */
--- 1597,1607 ----
* @param coder the coder of dst[]
*/
void getBytes(byte dst[], int dstBegin, byte coder) {
if (this.coder == coder) {
System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
! } else { // this.coder == LATIN1 && coder == UTF16
StringLatin1.inflateSB(value, dst, dstBegin, count);
}
}
/* for readObject() */
< prev index next >