java.lang.AbstractStringBuilder Maven / Gradle / Ivy
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package java.lang;
import static javaemul.internal.InternalPreconditions.checkStringElementIndex;
/**
* A base class to share implementation between {@link StringBuffer} and {@link StringBuilder}.
*
* Most methods will give expected performance results. Exception is {@link #setCharAt(int, char)},
* which is O(n), and thus should not be used many times on the same StringBuffer
.
*/
abstract class AbstractStringBuilder implements CharSequence, Appendable {
String string;
AbstractStringBuilder(String string) {
this.string = string;
}
@Override
public int length() {
return string.length();
}
public void setLength(int newLength) {
int oldLength = length();
if (newLength < oldLength) {
string = string.substring(0, newLength);
} else if (newLength > oldLength) {
string += String.valueOf(new char[newLength - oldLength]);
}
}
public int capacity() {
// This implementation does not track capacity.
return Integer.MAX_VALUE;
}
@SuppressWarnings("unused")
public void ensureCapacity(int ignoredCapacity) {
// This implementation does not track capacity
}
public void trimToSize() {
// This implementation does not track capacity
}
@Override
public char charAt(int index) {
return string.charAt(index);
}
public void getChars(int srcStart, int srcEnd, char[] dst, int dstStart) {
string.getChars(srcStart, srcEnd, dst, dstStart);
}
/**
* Warning! This method is much slower than the JRE implementation. If you need to do
* character level manipulation, you are strongly advised to use a char[] directly.
*/
public void setCharAt(int index, char x) {
replace0(index, index + 1, String.valueOf(x));
}
@Override
public CharSequence subSequence(int start, int end) {
return string.substring(start, end);
}
public String substring(int begin) {
return string.substring(begin);
}
public String substring(int begin, int end) {
return string.substring(begin, end);
}
public int indexOf(String x) {
return string.indexOf(x);
}
public int indexOf(String x, int start) {
return string.indexOf(x, start);
}
public int lastIndexOf(String s) {
return string.lastIndexOf(s);
}
public int lastIndexOf(String s, int start) {
return string.lastIndexOf(s, start);
}
@Override
public String toString() {
return string;
}
void appendCodePoint0(int x) {
string += String.fromCodePoint(x);
}
void replace0(int start, int end, String toInsert) {
int length = string.length();
if (end > length) {
end = length;
} else {
// Only checking for start > end; since rest is checked with substring.
checkStringElementIndex(start, end + 1);
}
string = string.substring(0, start) + toInsert + string.substring(end);
}
void reverse0() {
int length = string.length();
if (length <= 1) {
return;
}
char[] buffer = new char[length];
buffer[0] = string.charAt(length - 1);
for (int i = 1; i < length; i++) {
buffer[i] = string.charAt(length - 1 - i);
if (Character.isSurrogatePair(buffer[i], buffer[i - 1])) {
swap(buffer, i - 1, i);
}
}
string = new String(buffer);
}
private static void swap(char[] buffer, int f, int s) {
char tmp = buffer[f];
buffer[f] = buffer[s];
buffer[s] = tmp;
}
}