mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Adds support of java.io.BufferedReader and java.io.StringReader
This commit is contained in:
parent
744033b118
commit
03bc2e2e07
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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 org.teavm.classlib.java.io;
|
||||
|
||||
import org.teavm.classlib.java.lang.TIllegalArgumentException;
|
||||
import org.teavm.classlib.java.lang.TMath;
|
||||
import org.teavm.classlib.java.lang.TString;
|
||||
import org.teavm.classlib.java.lang.TStringBuilder;
|
||||
import org.teavm.classlib.java.util.TArrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TBufferedReader extends TReader {
|
||||
private TReader innerReader;
|
||||
private char[] buffer;
|
||||
private int index;
|
||||
private int count;
|
||||
private boolean eof;
|
||||
private int mark = -1;
|
||||
|
||||
public TBufferedReader(TReader innerReader, int size) {
|
||||
if (size < 0) {
|
||||
throw new TIllegalArgumentException();
|
||||
}
|
||||
this.innerReader = innerReader;
|
||||
this.buffer = new char[TMath.min(64, size)];
|
||||
}
|
||||
|
||||
public TBufferedReader(TReader innerReader) {
|
||||
this(innerReader, 1024);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws TIOException {
|
||||
requireOpened();
|
||||
if (index >= count) {
|
||||
if (!fillBuffer(0)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return buffer[index++];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws TIOException {
|
||||
requireOpened();
|
||||
innerReader.close();
|
||||
innerReader = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char[] cbuf, int off, int len) throws TIOException {
|
||||
requireOpened();
|
||||
if (index == count && eof) {
|
||||
return -1;
|
||||
}
|
||||
int charsRead = 0;
|
||||
while (charsRead < len) {
|
||||
int n = TMath.min(count - index, len - charsRead);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
cbuf[off++] = buffer[index++];
|
||||
}
|
||||
charsRead += n;
|
||||
if (!fillBuffer(0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return charsRead;
|
||||
}
|
||||
|
||||
public TString readLine() throws TIOException {
|
||||
requireOpened();
|
||||
if (eof && index == count) {
|
||||
return null;
|
||||
}
|
||||
TStringBuilder line = new TStringBuilder();
|
||||
while (true) {
|
||||
if (index >= count) {
|
||||
if (!fillBuffer(0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
char ch = buffer[index++];
|
||||
if (ch == '\n') {
|
||||
break;
|
||||
} else if (ch == '\r') {
|
||||
if (index >= count) {
|
||||
if (!fillBuffer(0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (buffer[index] == '\n') {
|
||||
++index;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
line.append(ch);
|
||||
}
|
||||
}
|
||||
return TString.wrap(line.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws TIOException {
|
||||
requireOpened();
|
||||
if (n < count - index) {
|
||||
index += n;
|
||||
} else {
|
||||
n -= (count - index);
|
||||
if (innerReader.skip(n) == n) {
|
||||
fillBuffer(0);
|
||||
}
|
||||
}
|
||||
return super.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ready() {
|
||||
return index < count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int readAheadLimit) throws TIOException {
|
||||
if (readAheadLimit > buffer.length) {
|
||||
buffer = TArrays.copyOf(buffer, readAheadLimit);
|
||||
}
|
||||
if (count - index < readAheadLimit) {
|
||||
for (int i = index; i < count; ++i) {
|
||||
buffer[i - index] = buffer[i];
|
||||
}
|
||||
fillBuffer(count - index);
|
||||
}
|
||||
mark = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws TIOException {
|
||||
if (mark == -1) {
|
||||
throw new TIOException();
|
||||
}
|
||||
index = mark;
|
||||
}
|
||||
|
||||
private boolean fillBuffer(int offset) throws TIOException {
|
||||
if (eof) {
|
||||
return false;
|
||||
}
|
||||
while (true) {
|
||||
int charsRead = innerReader.read(buffer, offset, buffer.length - 1);
|
||||
if (charsRead == -1) {
|
||||
eof = true;
|
||||
break;
|
||||
} else if (charsRead == 0) {
|
||||
break;
|
||||
} else {
|
||||
offset += charsRead;
|
||||
}
|
||||
}
|
||||
count = offset;
|
||||
index = 0;
|
||||
mark = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void requireOpened() {
|
||||
if (innerReader == null) {
|
||||
throw new TIOException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,5 +23,5 @@ import org.teavm.classlib.java.lang.TAutoCloseable;
|
|||
*/
|
||||
public interface TCloseable extends TAutoCloseable {
|
||||
@Override
|
||||
void close() throws TIOException;
|
||||
public void close() throws TIOException;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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 org.teavm.classlib.java.io;
|
||||
|
||||
import org.teavm.classlib.java.lang.TIllegalArgumentException;
|
||||
import org.teavm.classlib.java.lang.TMath;
|
||||
import org.teavm.classlib.java.lang.TNullPointerException;
|
||||
import org.teavm.classlib.java.lang.TString;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TStringReader extends TReader {
|
||||
private TString string;
|
||||
private int index;
|
||||
private int mark = 0;
|
||||
|
||||
public TStringReader(TString string) {
|
||||
if (string == null) {
|
||||
throw new TNullPointerException();
|
||||
}
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws TIOException {
|
||||
checkOpened();
|
||||
if (index >= string.length()) {
|
||||
return -1;
|
||||
}
|
||||
return string.charAt(index++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char[] cbuf, int off, int len) throws TIOException {
|
||||
checkOpened();
|
||||
if (index >= string.length()) {
|
||||
return -1;
|
||||
}
|
||||
int n = TMath.min(string.length() - index, len);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
cbuf[off++] = string.charAt(index++);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws TIOException {
|
||||
checkOpened();
|
||||
if (n < 0) {
|
||||
n = TMath.max(n, -index);
|
||||
} else {
|
||||
n = TMath.min(string.length() - index, n);
|
||||
}
|
||||
index += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ready() throws TIOException {
|
||||
checkOpened();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int readAheadLimit) throws TIOException {
|
||||
checkOpened();
|
||||
if (readAheadLimit < 0) {
|
||||
throw new TIllegalArgumentException();
|
||||
}
|
||||
mark = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws TIOException {
|
||||
checkOpened();
|
||||
index = mark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
string = null;
|
||||
}
|
||||
|
||||
private void checkOpened() throws TIOException {
|
||||
if (string == null) {
|
||||
throw new TIOException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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 org.teavm.classlib.java.lang;
|
||||
|
||||
import org.teavm.javascript.ni.Rename;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TByte extends TNumber implements TComparable<TByte> {
|
||||
private byte value;
|
||||
|
||||
public TByte(byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte byteValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static TByte valueOf(byte value) {
|
||||
return new TByte(value);
|
||||
}
|
||||
|
||||
public static TString toString(byte value) {
|
||||
return TString.wrap(new StringBuilder().append(value).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Rename("toString")
|
||||
public TString toString0() {
|
||||
return toString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(TObject other) {
|
||||
return other instanceof TByte && ((TByte)other).value == value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int compare(byte a, byte b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TByte other) {
|
||||
return compare(value, other.value);
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import org.teavm.classlib.impl.charset.UTF16Helper;
|
||||
import org.teavm.classlib.impl.unicode.UnicodeHelper;
|
||||
import org.teavm.dependency.PluggableDependency;
|
||||
import org.teavm.javascript.ni.GeneratedBy;
|
||||
|
@ -109,4 +110,23 @@ public class TCharacter extends TObject {
|
|||
@GeneratedBy(CharacterNativeGenerator.class)
|
||||
@PluggableDependency(CharacterNativeGenerator.class)
|
||||
private static native String obtainDigitMapping();
|
||||
|
||||
public static int toChars(int codePoint, char[] dst, int dstIndex) {
|
||||
if (codePoint >= UTF16Helper.SUPPLEMENTARY_PLANE) {
|
||||
dst[dstIndex] = UTF16Helper.highSurrogate(codePoint);
|
||||
dst[dstIndex + 1] = UTF16Helper.lowSurrogate(codePoint);
|
||||
return 2;
|
||||
} else {
|
||||
dst[dstIndex] = (char)codePoint;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static char[] toChars(int codePoint) {
|
||||
if (codePoint >= UTF16Helper.SUPPLEMENTARY_PLANE) {
|
||||
return new char[] { UTF16Helper.highSurrogate(codePoint), UTF16Helper.lowSurrogate(codePoint) };
|
||||
} else {
|
||||
return new char[] { (char)codePoint };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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 org.teavm.classlib.java.lang;
|
||||
|
||||
import org.teavm.javascript.ni.Rename;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TShort extends TNumber implements TComparable<TShort> {
|
||||
private short value;
|
||||
|
||||
public TShort(short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short shortValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static TShort valueOf(short value) {
|
||||
return new TShort(value);
|
||||
}
|
||||
|
||||
public static TString toString(short value) {
|
||||
return TString.wrap(new StringBuilder().append(value).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Rename("toString")
|
||||
public TString toString0() {
|
||||
return toString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(TObject other) {
|
||||
return other instanceof TShort && ((TShort)other).value == value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int compare(short a, short b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TShort other) {
|
||||
return compare(value, other.value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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 org.teavm.classlib.java.io;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class BufferedReaderTest {
|
||||
@Test
|
||||
public void readsCharacters() throws IOException {
|
||||
String str = "foo bar baz";
|
||||
BufferedReader reader = new BufferedReader(new StringReader(str));
|
||||
char[] chars = new char[100];
|
||||
int charsRead = reader.read(chars);
|
||||
assertEquals(str.length(), charsRead);
|
||||
assertEquals(str.charAt(0), chars[0]);
|
||||
assertEquals(str.charAt(charsRead - 1), chars[charsRead - 1]);
|
||||
assertEquals(0, chars[charsRead]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readsCharactersOneByOne() throws IOException {
|
||||
String str = "foo";
|
||||
BufferedReader reader = new BufferedReader(new StringReader(str));
|
||||
assertEquals('f', reader.read());
|
||||
assertEquals('o', reader.read());
|
||||
assertEquals('o', reader.read());
|
||||
assertEquals(-1, reader.read());
|
||||
assertEquals(-1, reader.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readsLine() throws IOException {
|
||||
String str = "foo\nbar\rbaz\r\nA\n\nB";
|
||||
BufferedReader reader = new BufferedReader(new StringReader(str));
|
||||
assertEquals("foo", reader.readLine());
|
||||
assertEquals("bar", reader.readLine());
|
||||
assertEquals("baz", reader.readLine());
|
||||
assertEquals("A", reader.readLine());
|
||||
assertEquals("", reader.readLine());
|
||||
assertEquals("B", reader.readLine());
|
||||
assertNull(reader.readLine());
|
||||
assertNull(reader.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fillsBuffer() throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
sb.append((char)i);
|
||||
}
|
||||
BufferedReader reader = new BufferedReader(new StringReader(sb.toString()), 101);
|
||||
char[] buffer = new char[500];
|
||||
reader.read(buffer);
|
||||
assertEquals(0, buffer[0]);
|
||||
assertEquals(1, buffer[1]);
|
||||
assertEquals(499, buffer[499]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void leavesMark() throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
sb.append((char)i);
|
||||
}
|
||||
BufferedReader reader = new BufferedReader(new StringReader(sb.toString()), 100);
|
||||
reader.skip(50);
|
||||
reader.mark(70);
|
||||
reader.skip(60);
|
||||
reader.reset();
|
||||
char[] buffer = new char[150];
|
||||
int charsRead = reader.read(buffer);
|
||||
assertEquals(150, charsRead);
|
||||
assertEquals(50, buffer[0]);
|
||||
assertEquals(51, buffer[1]);
|
||||
assertEquals(199, buffer[149]);
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.io;
|
||||
package org.teavm.classlib.java.io;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.io.ByteArrayInputStream;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.util;
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.ArrayList;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.util;
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.Arrays;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.util;
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import java.util.ArrayList;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.util;
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.ServiceLoader;
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.util;
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
/**
|
||||
*
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.util;
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
/**
|
||||
*
|
|
@ -1 +0,0 @@
|
|||
org.teavm.classlib.java.lang.util.TestServiceImpl
|
|
@ -0,0 +1 @@
|
|||
org.teavm.classlib.java.util.TestServiceImpl
|
|
@ -411,7 +411,15 @@ class DependencyGraphBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void isInstance(VariableReader receiver, VariableReader value, ValueType type) {
|
||||
public void isInstance(VariableReader receiver, VariableReader value, final ValueType type) {
|
||||
if (type instanceof ValueType.Object) {
|
||||
final String className = ((ValueType.Object)type).getClassName();
|
||||
useRunners.add(new Runnable() {
|
||||
@Override public void run() {
|
||||
dependencyChecker.initClass(className, callerStack);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue
Block a user