diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Charset.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Charset.java deleted file mode 100644 index 8bf3d0d44..000000000 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Charset.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.teavm.classlib.impl.charset; - -/** - * - * @author Alexey Andreev - */ -@CharsetName("UTF-16") -public class UTF16Charset { - -} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Helper.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Helper.java new file mode 100644 index 000000000..9396db9da --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/UTF16Helper.java @@ -0,0 +1,39 @@ +package org.teavm.classlib.impl.charset; + +/** + * + * @author Alexey Andreev + */ +public class UTF16Helper { + public static final int SURROGATE_BIT_MASK = 0xFC00; + public static final int SURROGATE_BIT_INV_MASK = 0x03FF; + public static final int HIGH_SURROGATE_BITS = 0xF800; + public static final int LOW_SURROGATE_BITS = 0xF800; + public static final int MEANINGFUL_SURROGATE_BITS = 10; + public static final int SUPPLEMENTARY_PLANE = 0x10000; + + public static char highSurrogate(int codePoint) { + return (char)(HIGH_SURROGATE_BITS | (codePoint >> MEANINGFUL_SURROGATE_BITS) & SURROGATE_BIT_INV_MASK); + } + + public static char lowSurrogate(int codePoint) { + return (char)(HIGH_SURROGATE_BITS | codePoint & SURROGATE_BIT_INV_MASK); + } + + public static boolean isHighSurrogate(char c) { + return (c & SURROGATE_BIT_MASK) == HIGH_SURROGATE_BITS; + } + + public static boolean isLowSurrogate(char c) { + return (c & SURROGATE_BIT_MASK) == LOW_SURROGATE_BITS; + } + + public static boolean isSurrogatePair(char a, char b) { + return isHighSurrogate(a) && isLowSurrogate(b); + } + + public static int buildCodePoint(char a, char b) { + return ((a & SURROGATE_BIT_INV_MASK) << MEANINGFUL_SURROGATE_BITS) | + (b & SURROGATE_BIT_INV_MASK) + SUPPLEMENTARY_PLANE; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java index a8e143a4d..775937ecb 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TAbstractStringBuilder.java @@ -1,5 +1,6 @@ package org.teavm.classlib.java.lang; +import org.teavm.classlib.impl.charset.UTF16Helper; import org.teavm.classlib.java.lang.io.TSerializable; import org.teavm.classlib.java.util.TArrays; import org.teavm.javascript.ni.Remove; @@ -289,13 +290,13 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ } protected TAbstractStringBuilder appendCodePoint(int codePoint) { - if (codePoint < TString.SUPPLEMENTARY_PLANE) { + if (codePoint < UTF16Helper.SUPPLEMENTARY_PLANE) { return append((char)codePoint); } ensureCapacity(length + 2); - codePoint -= TString.SUPPLEMENTARY_PLANE; - buffer[length++] = TString.highSurrogate(codePoint); - buffer[length++] = TString.lowSurrogate(codePoint); + codePoint -= UTF16Helper.SUPPLEMENTARY_PLANE; + buffer[length++] = UTF16Helper.highSurrogate(codePoint); + buffer[length++] = UTF16Helper.lowSurrogate(codePoint); return this; } @@ -362,6 +363,6 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ } public void setLength(int newLength) { - length = 0; + length = newLength; } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java index af5ab3ae9..fb35e560d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java @@ -1,5 +1,6 @@ package org.teavm.classlib.java.lang; +import org.teavm.classlib.impl.charset.UTF16Helper; import org.teavm.classlib.java.lang.io.TSerializable; import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.ni.Rename; @@ -10,12 +11,6 @@ import org.teavm.javascript.ni.Rename; */ public class TString extends TObject implements TSerializable, TComparable, 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 transient int hashCode; @@ -54,29 +49,26 @@ public class TString extends TObject implements TSerializable, TComparable> 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) { + if (ch < UTF16Helper.SUPPLEMENTARY_PLANE) { char bmpChar = (char)ch; for (int i = fromIndex; i < characters.length; ++i) { if (characters[i] == bmpChar) { @@ -211,8 +194,8 @@ public class TString extends TObject implements TSerializable, TComparable= 0; --i) { if (characters[i] == bmpChar) { @@ -236,8 +219,8 @@ public class TString extends TObject implements TSerializable, TComparable= 1; --i) { if (characters[i] == lo && characters[i - 1] == hi) { return i; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TPrintStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TPrintStream.java index 69ad1feb7..48bcd7d30 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TPrintStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/io/TPrintStream.java @@ -1,5 +1,6 @@ package org.teavm.classlib.java.lang.io; +import org.teavm.classlib.java.lang.TMath; import org.teavm.classlib.java.lang.TStringBuilder; /** @@ -95,7 +96,16 @@ public class TPrintStream extends TFilterOutputStream { } public void print(char[] s) { + print(s, 0, s.length); + } + private void print(char[] s, int begin, int end) { + int[] codePoints = new int[TMath.min(s.length, 4096)]; + } + + public void print(char c) { + buffer[0] = c; + print(buffer, 0, 1); } public void print(int i) {