mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Adds byte array to string converter
This commit is contained in:
parent
97107a2953
commit
55218aba4b
|
@ -54,6 +54,10 @@ public class ByteBuffer {
|
|||
return pos == end;
|
||||
}
|
||||
|
||||
public void skip(int count) {
|
||||
pos += count;
|
||||
}
|
||||
|
||||
public byte get() {
|
||||
return data[pos++];
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class UTF16Helper {
|
|||
}
|
||||
|
||||
public static char lowSurrogate(int codePoint) {
|
||||
return (char)(HIGH_SURROGATE_BITS | codePoint & SURROGATE_BIT_INV_MASK);
|
||||
return (char)(LOW_SURROGATE_BITS | codePoint & SURROGATE_BIT_INV_MASK);
|
||||
}
|
||||
|
||||
public static boolean isHighSurrogate(char c) {
|
||||
|
|
|
@ -53,6 +53,40 @@ public class UTF8Charset extends Charset {
|
|||
|
||||
@Override
|
||||
public void decode(ByteBuffer source, CharBuffer dest) {
|
||||
|
||||
while (!source.end() && dest.available() >= 2) {
|
||||
int b = source.get() & 0xFF;
|
||||
if ((b & 0x80) == 0) {
|
||||
dest.put((char)b);
|
||||
} else if ((b & 0xE0) == 0xC0) {
|
||||
if (source.end()) {
|
||||
dest.put((char)b);
|
||||
return;
|
||||
}
|
||||
dest.put((char)(((b & 0x1F) << 6) | (source.get() & 0x3F)));
|
||||
} else if ((b & 0xF0) == 0xE0) {
|
||||
if (source.available() < 2) {
|
||||
source.skip(source.available());
|
||||
dest.put((char)b);
|
||||
return;
|
||||
}
|
||||
byte b2 = source.get();
|
||||
byte b3 = source.get();
|
||||
char c = (char)(((b & 0x0F) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3F));
|
||||
dest.put(!UTF16Helper.isHighSurrogate(c) ? c : '?');
|
||||
} else if ((b & 0xF8) == 0xF0) {
|
||||
if (source.available() < 3) {
|
||||
source.skip(source.available());
|
||||
dest.put((char)b);
|
||||
return;
|
||||
}
|
||||
byte b2 = source.get();
|
||||
byte b3 = source.get();
|
||||
byte b4 = source.get();
|
||||
int code = (((b & 0x07) << 18) | ((b2 & 0x3f) << 12) | ((b3 & 0x3F) << 6) | (b4 & 0x3F)) -
|
||||
UTF16Helper.SUPPLEMENTARY_PLANE;
|
||||
dest.put(UTF16Helper.highSurrogate(code));
|
||||
dest.put(UTF16Helper.lowSurrogate(code));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
|
|||
private static final int FLOAT_MAX_POS = 1000000;
|
||||
private static final long DOUBLE_MAX_POS = 1000000000000000L;
|
||||
char[] buffer;
|
||||
int length;
|
||||
private int length;
|
||||
|
||||
public TAbstractStringBuilder() {
|
||||
this(16);
|
||||
|
@ -490,6 +490,11 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
|
|||
return this;
|
||||
}
|
||||
|
||||
protected TAbstractStringBuilder append(TObject obj) {
|
||||
append(TString.wrap(obj != null ? obj.toString() : "null"));
|
||||
return this;
|
||||
}
|
||||
|
||||
private void ensureCapacity(int capacity) {
|
||||
if (buffer.length >= capacity) {
|
||||
return;
|
||||
|
@ -522,7 +527,7 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
|
|||
return buffer[index];
|
||||
}
|
||||
|
||||
public TAbstractStringBuilder append(TCharSequence s, int start, int end) {
|
||||
protected TAbstractStringBuilder append(TCharSequence s, int start, int end) {
|
||||
if (start > end || end > s.length() || start < 0) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
|
@ -533,10 +538,19 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
|
|||
return this;
|
||||
}
|
||||
|
||||
public TAbstractStringBuilder append(TCharSequence s) {
|
||||
protected TAbstractStringBuilder append(TCharSequence s) {
|
||||
return append(s, 0, s.length());
|
||||
}
|
||||
|
||||
protected TAbstractStringBuilder append(char[] chars, int offset, int len) {
|
||||
ensureCapacity(length + len);
|
||||
len += offset;
|
||||
while (offset < len) {
|
||||
buffer[length++] = chars[offset++];
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TCharSequence subSequence(int start, int end) {
|
||||
// TODO: implement
|
||||
|
|
|
@ -15,8 +15,12 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import org.teavm.classlib.impl.charset.ByteBuffer;
|
||||
import org.teavm.classlib.impl.charset.CharBuffer;
|
||||
import org.teavm.classlib.impl.charset.Charset;
|
||||
import org.teavm.classlib.impl.charset.UTF16Helper;
|
||||
import org.teavm.classlib.java.io.TSerializable;
|
||||
import org.teavm.classlib.java.io.TUnsupportedEncodingException;
|
||||
import org.teavm.javascript.ni.GeneratedBy;
|
||||
import org.teavm.javascript.ni.Rename;
|
||||
|
||||
|
@ -24,8 +28,7 @@ import org.teavm.javascript.ni.Rename;
|
|||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class TString extends TObject implements TSerializable, TComparable<TString>,
|
||||
TCharSequence {
|
||||
public class TString extends TObject implements TSerializable, TComparable<TString>, TCharSequence {
|
||||
private char[] characters;
|
||||
private transient int hashCode;
|
||||
|
||||
|
@ -51,8 +54,43 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
|
|||
}
|
||||
}
|
||||
|
||||
public TString(byte[] bytes, int offset, int length, TString charsetName) throws TUnsupportedEncodingException {
|
||||
Charset charset = Charset.get(charsetName.toString());
|
||||
if (charset == null) {
|
||||
throw new TUnsupportedEncodingException(TString.wrap("Unknown encoding:" + charsetName));
|
||||
}
|
||||
initWithBytes(bytes, offset, length, charset);
|
||||
}
|
||||
|
||||
public TString(byte[] bytes, int offset, int length) {
|
||||
initWithBytes(bytes, offset, length, Charset.get("UTF-8"));
|
||||
}
|
||||
|
||||
public TString(byte[] bytes) {
|
||||
this(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
public TString(byte[] bytes, TString charsetName) throws TUnsupportedEncodingException {
|
||||
this(bytes, 0, bytes.length, charsetName);
|
||||
}
|
||||
|
||||
private void initWithBytes(byte[] bytes, int offset, int length, Charset charset) {
|
||||
TStringBuilder sb = new TStringBuilder(bytes.length * 2);
|
||||
this.characters = new char[sb.length()];
|
||||
ByteBuffer source = new ByteBuffer(bytes, offset, offset + length);
|
||||
char[] destChars = new char[TMath.max(8, TMath.min(length * 2, 1024))];
|
||||
CharBuffer dest = new CharBuffer(destChars, 0, length * 2);
|
||||
while (!source.end()) {
|
||||
charset.decode(source, dest);
|
||||
sb.append(destChars, 0, dest.position());
|
||||
dest.rewind(0);
|
||||
}
|
||||
characters = new char[sb.length()];
|
||||
sb.getChars(0, sb.length(), characters, 0);
|
||||
}
|
||||
|
||||
public TString(TStringBuilder sb) {
|
||||
this(sb.buffer, 0, sb.length);
|
||||
this(sb.buffer, 0, sb.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,14 @@ package org.teavm.classlib.java.lang;
|
|||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TStringBuilder extends TAbstractStringBuilder {
|
||||
public TStringBuilder(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
public TStringBuilder() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TStringBuilder append(TString string) {
|
||||
super.append(string);
|
||||
|
@ -56,6 +64,12 @@ public class TStringBuilder extends TAbstractStringBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TStringBuilder append(char[] chars, int offset, int len) {
|
||||
super.append(chars, offset, len);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TStringBuilder appendCodePoint(int codePoint) {
|
||||
super.appendCodePoint(codePoint);
|
||||
|
@ -73,4 +87,10 @@ public class TStringBuilder extends TAbstractStringBuilder {
|
|||
super.append(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TStringBuilder append(TObject obj) {
|
||||
super.append(obj);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -205,4 +206,16 @@ public class StringTest {
|
|||
assertEquals('2', array[1]);
|
||||
assertEquals('3', array[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createdFromByteArray() throws UnsupportedEncodingException {
|
||||
byte[] bytes = { 49, 50, 51 };
|
||||
assertEquals("123", new String(bytes, "UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createdFromUTF8ByteArray() throws UnsupportedEncodingException {
|
||||
byte[] bytes = { 65, -62, -69, -32, -82, -69, -16, -66, -78, -69 };
|
||||
assertEquals("A\u00BB\u0BBB\uD8BB\uDCBB", new String(bytes, "UTF-8"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user