mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds java.lang.String methods
This commit is contained in:
parent
626635daeb
commit
4767ab07cb
|
@ -34,4 +34,12 @@ public class StringBuilderTests {
|
||||||
sb.append(2147483647);
|
sb.append(2147483647);
|
||||||
assertEquals("2147483647", sb.toString());
|
assertEquals("2147483647", sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void appendsCodePoint() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.appendCodePoint(969356);
|
||||||
|
assertEquals(56178, sb.charAt(0));
|
||||||
|
assertEquals(56972, sb.charAt(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,4 +77,91 @@ public class StringTests {
|
||||||
public void startsWithWorks() {
|
public void startsWithWorks() {
|
||||||
assertTrue("123".startsWith("12"));
|
assertTrue("123".startsWith("12"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void regionsMatched() {
|
||||||
|
assertTrue("12345".regionMatches(2, "23456", 1, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void endsWithWorkds() {
|
||||||
|
assertTrue("12345".endsWith("45"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exposesSupplementaryCodePoint() {
|
||||||
|
String str = new String(new char[] { (char)56178, (char)56972 });
|
||||||
|
assertEquals(969356, str.codePointAt(0));
|
||||||
|
assertEquals(56972, str.codePointAt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exposesWrongSurrogates() {
|
||||||
|
String str = new String(new char[] { (char)56972, (char)56178 });
|
||||||
|
assertEquals(56972, str.codePointAt(0));
|
||||||
|
assertEquals(56178, str.codePointAt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void exposesSupplementaryCodePointBefore() {
|
||||||
|
String str = new String(new char[] { (char)56178, (char)56972 });
|
||||||
|
assertEquals(969356, str.codePointBefore(2));
|
||||||
|
assertEquals(56178, str.codePointBefore(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void countsCodePoints() {
|
||||||
|
String str = new String(new char[] { (char)56178, (char)56972, 'a', 'b' });
|
||||||
|
assertEquals(3, str.codePointCount(0, 4));
|
||||||
|
assertEquals(1, str.codePointCount(0, 2));
|
||||||
|
assertEquals(2, str.codePointCount(2, 4));
|
||||||
|
assertEquals(3, str.codePointCount(1, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givesOffsetByCodePoint() {
|
||||||
|
String str = new String(new char[] { (char)56178, (char)56972, 'a', 'b' });
|
||||||
|
assertEquals(2, str.offsetByCodePoints(0, 1));
|
||||||
|
assertEquals(2, str.offsetByCodePoints(1, 1));
|
||||||
|
assertEquals(4, str.offsetByCodePoints(0, 3));
|
||||||
|
assertEquals(4, str.offsetByCodePoints(1, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findsCodePoint() {
|
||||||
|
String str = new String(new char[] { 'a', 'b', (char)56178, (char)56972, 'c',
|
||||||
|
(char)56178, (char)56972, 'c', 'd' });
|
||||||
|
assertEquals(2, str.indexOf(969356));
|
||||||
|
assertEquals(4, str.indexOf('c'));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findsCodePointBackward() {
|
||||||
|
String str = new String(new char[] { 'a', 'b', (char)56178, (char)56972, 'c',
|
||||||
|
(char)56178, (char)56972, 'c', 'd' });
|
||||||
|
assertEquals(5, str.lastIndexOf(969356));
|
||||||
|
assertEquals(7, str.lastIndexOf('c'));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findsString() {
|
||||||
|
assertEquals(1, "abcdbcd".indexOf("bc"));
|
||||||
|
assertEquals(-1, "abcdbcd".indexOf("bb"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findsStringBackward() {
|
||||||
|
assertEquals(4, "abcdbcd".lastIndexOf("bc"));
|
||||||
|
assertEquals(-1, "abcdbcd".lastIndexOf("bb"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void concatenatesStrings() {
|
||||||
|
assertEquals("abcd", "ab".concat("cd"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void replacesCharacter() {
|
||||||
|
assertEquals("abbdbbd", "abcdbcd".replace('c', 'b'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,17 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected TAbstractStringBuilder appendCodePoint(int codePoint) {
|
||||||
|
if (codePoint < TString.SUPPLEMENTARY_PLANE) {
|
||||||
|
return append((char)codePoint);
|
||||||
|
}
|
||||||
|
ensureCapacity(length + 2);
|
||||||
|
codePoint -= TString.SUPPLEMENTARY_PLANE;
|
||||||
|
buffer[length++] = TString.highSurrogate(codePoint);
|
||||||
|
buffer[length++] = TString.lowSurrogate(codePoint);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private void ensureCapacity(int capacity) {
|
private void ensureCapacity(int capacity) {
|
||||||
if (buffer.length >= capacity) {
|
if (buffer.length >= capacity) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,7 +7,14 @@ import org.teavm.javascript.ni.GeneratedBy;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class TString extends TObject implements TSerializable, TComparable<TString> {
|
public class TString extends TObject implements TSerializable, TComparable<TString>,
|
||||||
|
TCharSequence {
|
||||||
|
static int SURROGATE_BIT_MASK = 0xFC00;
|
||||||
|
static int SURROGATE_BIT_INV_MASK = 0x03FF;
|
||||||
|
static int HIGH_SURROGATE_BITS = 0xF800;
|
||||||
|
static int LOW_SURROGATE_BITS = 0xF800;
|
||||||
|
static int MEANINGFUL_SURROGATE_BITS = 10;
|
||||||
|
static int SUPPLEMENTARY_PLANE = 0x10000;
|
||||||
private char[] characters;
|
private char[] characters;
|
||||||
private transient int hashCode;
|
private transient int hashCode;
|
||||||
|
|
||||||
|
@ -37,13 +44,57 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
|
||||||
this(sb.buffer, 0, sb.length);
|
this(sb.buffer, 0, sb.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public char charAt(int index) {
|
public char charAt(int index) {
|
||||||
if (index < 0 || index >= characters.length) {
|
if (index < 0 || index >= characters.length) {
|
||||||
throw new StringIndexOutOfBoundsException(null);
|
throw new TStringIndexOutOfBoundsException(null);
|
||||||
}
|
}
|
||||||
return characters[index];
|
return characters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int codePointAt(int index) {
|
||||||
|
if (index == characters.length - 1 || (characters[index] & SURROGATE_BIT_MASK) != HIGH_SURROGATE_BITS ||
|
||||||
|
(characters[index + 1] & SURROGATE_BIT_MASK) != LOW_SURROGATE_BITS) {
|
||||||
|
return characters[index];
|
||||||
|
}
|
||||||
|
return ((characters[index] & SURROGATE_BIT_INV_MASK) << MEANINGFUL_SURROGATE_BITS) |
|
||||||
|
(characters[index + 1] & SURROGATE_BIT_INV_MASK) + SUPPLEMENTARY_PLANE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int codePointBefore(int index) {
|
||||||
|
if (index == 1 || (characters[index] & SURROGATE_BIT_MASK) != LOW_SURROGATE_BITS ||
|
||||||
|
(characters[index - 1] & SURROGATE_BIT_MASK) != HIGH_SURROGATE_BITS) {
|
||||||
|
return characters[index - 1];
|
||||||
|
}
|
||||||
|
return ((characters[index - 1] & SURROGATE_BIT_INV_MASK) << MEANINGFUL_SURROGATE_BITS) |
|
||||||
|
(characters[index] & SURROGATE_BIT_INV_MASK) + SUPPLEMENTARY_PLANE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int codePointCount(int beginIndex, int endIndex) {
|
||||||
|
int count = endIndex;
|
||||||
|
--endIndex;
|
||||||
|
for (int i = beginIndex; i < endIndex; ++i) {
|
||||||
|
if ((characters[i] & SURROGATE_BIT_MASK) == HIGH_SURROGATE_BITS &&
|
||||||
|
(characters[i + 1] & SURROGATE_BIT_MASK) == LOW_SURROGATE_BITS) {
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int offsetByCodePoints(int index, int codePointOffset) {
|
||||||
|
for (int i = 0; i < codePointOffset; ++i) {
|
||||||
|
if (index < characters.length - 1 && (characters[index] & SURROGATE_BIT_MASK) == HIGH_SURROGATE_BITS &&
|
||||||
|
(characters[index + 1] & SURROGATE_BIT_MASK) == LOW_SURROGATE_BITS) {
|
||||||
|
index += 2;
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int length() {
|
public int length() {
|
||||||
return characters.length;
|
return characters.length;
|
||||||
}
|
}
|
||||||
|
@ -106,9 +157,177 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean startsWith(TString prefix) {
|
public boolean startsWith(TString prefix) {
|
||||||
|
if (this == prefix) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return startsWith(prefix, 0);
|
return startsWith(prefix, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean regionMatches(int toffset, TString other, int ooffset, int len) {
|
||||||
|
if (toffset < 0 || ooffset < 0 || toffset + len > length() || ooffset + len > other.length()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
if (charAt(toffset++) != other.charAt(ooffset++)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean endsWith(TString suffix) {
|
||||||
|
if (this == suffix) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (suffix.length() > length()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int j = 0;
|
||||||
|
for (int i = length() - suffix.length(); i < length(); ++i) {
|
||||||
|
if (charAt(i) != suffix.charAt(j++)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char highSurrogate(int codePoint) {
|
||||||
|
return (char)(TString.HIGH_SURROGATE_BITS | (codePoint >> TString.MEANINGFUL_SURROGATE_BITS) &
|
||||||
|
TString.SURROGATE_BIT_INV_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char lowSurrogate(int codePoint) {
|
||||||
|
return (char)(TString.HIGH_SURROGATE_BITS | codePoint & TString.SURROGATE_BIT_INV_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(int ch, int fromIndex) {
|
||||||
|
if (ch < SUPPLEMENTARY_PLANE) {
|
||||||
|
char bmpChar = (char)ch;
|
||||||
|
for (int i = fromIndex; i < characters.length; ++i) {
|
||||||
|
if (characters[i] == bmpChar) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
char hi = highSurrogate(ch);
|
||||||
|
char lo = lowSurrogate(ch);
|
||||||
|
for (int i = fromIndex; i < characters.length - 1; ++i) {
|
||||||
|
if (characters[i] == hi && characters[i + 1] == lo) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(int ch) {
|
||||||
|
return indexOf(ch, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(int ch, int fromIndex) {
|
||||||
|
if (ch < SUPPLEMENTARY_PLANE) {
|
||||||
|
char bmpChar = (char)ch;
|
||||||
|
for (int i = fromIndex; i >= 0; --i) {
|
||||||
|
if (characters[i] == bmpChar) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
char hi = highSurrogate(ch);
|
||||||
|
char lo = lowSurrogate(ch);
|
||||||
|
for (int i = fromIndex; i >= 1; --i) {
|
||||||
|
if (characters[i] == lo && characters[i - 1] == hi) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(int ch) {
|
||||||
|
return lastIndexOf(ch, length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(TString str, int fromIndex) {
|
||||||
|
int toIndex = length() - str.length();
|
||||||
|
outer:
|
||||||
|
for (int i = fromIndex; i < toIndex; ++i) {
|
||||||
|
for (int j = 0; j < str.length(); ++j) {
|
||||||
|
if (charAt(i + j) != str.charAt(j)) {
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(TString str) {
|
||||||
|
return indexOf(str, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(TString str, int fromIndex) {
|
||||||
|
fromIndex = Math.min(fromIndex, length() - str.length());
|
||||||
|
outer:
|
||||||
|
for (int i = fromIndex; i >= 0; --i) {
|
||||||
|
for (int j = 0; j < str.length(); ++j) {
|
||||||
|
if (charAt(i + j) != str.charAt(j)) {
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(TString str) {
|
||||||
|
return lastIndexOf(str, length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TString substring(int beginIndex, int endIndex) {
|
||||||
|
if (beginIndex > endIndex) {
|
||||||
|
throw new TIndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return new TString(characters, beginIndex, endIndex - beginIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TString substring(int beginIndex) {
|
||||||
|
return substring(beginIndex, length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TCharSequence subSequence(int beginIndex, int endIndex) {
|
||||||
|
return substring(beginIndex, endIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TString concat(TString str) {
|
||||||
|
if (str.isEmpty()) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
char[] buffer = new char[length() + str.length()];
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < length(); ++i) {
|
||||||
|
buffer[index++] = charAt(i);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < str.length(); ++i) {
|
||||||
|
buffer[index++] = str.charAt(i);
|
||||||
|
}
|
||||||
|
return new TString(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TString replace(char oldChar, char newChar) {
|
||||||
|
if (oldChar == newChar) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
char[] buffer = new char[length()];
|
||||||
|
for (int i = 0; i < length(); ++i) {
|
||||||
|
buffer[i] = charAt(i) == oldChar ? newChar : charAt(i);
|
||||||
|
}
|
||||||
|
return new TString(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
public static TString valueOf(int index) {
|
public static TString valueOf(int index) {
|
||||||
return new TStringBuilder().append(index).toString0();
|
return new TStringBuilder().append(index).toString0();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,10 @@ public class TStringBuilder extends TAbstractStringBuilder {
|
||||||
super.append(c);
|
super.append(c);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TStringBuilder appendCodePoint(int codePoint) {
|
||||||
|
super.appendCodePoint(codePoint);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user