diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharBuffer.java index b2332d2ef..52c700ac4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/charset/CharBuffer.java @@ -62,6 +62,10 @@ public class CharBuffer { return pos; } + public void skip(int count) { + pos += count; + } + public void put(CharBuffer buffer) { while (buffer.pos < buffer.end) { data[pos++] = buffer.data[buffer.pos++]; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TByteArrayInputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TByteArrayInputStream.java new file mode 100644 index 000000000..b6963a49e --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TByteArrayInputStream.java @@ -0,0 +1,85 @@ +/* + * 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.TMath; + +/** + * + * @author Alexey Andreev + */ +public class TByteArrayInputStream extends TInputStream { + protected byte[] buf; + protected int pos; + protected int mark; + protected int count; + + public TByteArrayInputStream(byte[] buf, int offset, int length) { + this.buf = buf; + pos = offset; + mark = offset; + count = offset + length; + } + + public TByteArrayInputStream(byte[] buf) { + this(buf, 0, buf.length); + } + + @Override + public int read() { + return pos < count ? buf[pos++] : -1; + } + + @Override + public int read(byte[] b, int off, int len) { + int bytesToRead = TMath.min(len, count - pos); + for (int i = 0; i < bytesToRead; ++i) { + b[off++] = buf[pos++]; + } + return bytesToRead > 0 ? bytesToRead : -1; + } + + @Override + public long skip(long n) { + int bytesSkipped = (int)TMath.min(n, count - pos); + pos += bytesSkipped; + return bytesSkipped; + } + + @Override + public int available() { + return count - pos; + } + + @Override + public boolean markSupported() { + return true; + } + + @Override + public void mark(int readAheadLimit) { + mark = pos; + } + + @Override + public void reset() { + pos = mark; + } + + @Override + public void close() { + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStream.java new file mode 100644 index 000000000..8e0255e65 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStream.java @@ -0,0 +1,86 @@ +/* + * 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.TInteger; +import org.teavm.classlib.java.lang.TObject; + +/** + * + * @author Alexey Andreev + */ +public abstract class TInputStream extends TObject implements TCloseable { + public TInputStream() { + } + + public abstract int read() throws TIOException; + + public int read(byte[] b) throws TIOException { + return read(b, 0, b.length); + } + + public int read(byte[] b, int off, int len) throws TIOException { + for (int i = 0; i < len; ++i) { + int bt = read(); + if (bt < 0) { + return i; + } + b[off++] = (byte)bt; + } + return len > 0 ? len : -1; + } + + public long skip(long n) throws TIOException { + if (n < TInteger.MAX_VALUE) { + return skip((int)n); + } else { + for (long i = 0; i < n; ++i) { + if (read() < 0) { + return i; + } + } + return n; + } + } + + private int skip(int n) throws TIOException { + for (int i = 0; i < n; ++i) { + if (read() < 0) { + return i; + } + } + return n; + } + + public int available() throws TIOException { + return 0; + } + + @Override + public void close() throws TIOException { + } + + public void mark(@SuppressWarnings("unused") int readlimit) { + } + + public void reset() throws TIOException { + throw new TIOException(); + } + + public boolean markSupported() { + return false; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStreamReader.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStreamReader.java new file mode 100644 index 000000000..2a39581aa --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStreamReader.java @@ -0,0 +1,133 @@ +/* + * 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.impl.charset.ByteBuffer; +import org.teavm.classlib.impl.charset.CharBuffer; +import org.teavm.classlib.impl.charset.Charset; +import org.teavm.classlib.impl.charset.UTF8Charset; +import org.teavm.classlib.java.lang.TString; + +/** + * + * @author Alexey Andreev + */ +public class TInputStreamReader extends TReader { + private TInputStream stream; + private Charset charset; + private TString charsetName; + private byte[] inData = new byte[8192]; + private ByteBuffer inBuffer = new ByteBuffer(inData); + private char[] outData = new char[1024]; + private CharBuffer outBuffer = new CharBuffer(outData); + private boolean streamEof; + private boolean eof; + + public TInputStreamReader(TInputStream in, TString charsetName) { + this(in, Charset.get(charsetName.toString())); + this.charsetName = charsetName; + } + + public TInputStreamReader(TInputStream in) { + this(in, new UTF8Charset()); + charsetName = TString.wrap("UTF-8"); + } + + private TInputStreamReader(TInputStream in, Charset charset) { + this.stream = in; + this.charset = charset; + outBuffer.skip(outBuffer.available()); + inBuffer.skip(inBuffer.available()); + } + + public TString getEncoding() { + return charsetName; + } + + @Override + public void close() throws TIOException { + stream.close(); + } + + @Override + public int read() throws TIOException { + if (eof) { + return -1; + } + if (!outBuffer.end()) { + return outBuffer.get(); + } + return fillBuffer() ? outBuffer.get() : -1; + } + + @Override + public int read(char[] cbuf, int off, int len) throws TIOException { + CharBuffer wrapBuffer = new CharBuffer(cbuf, off, off + len); + while (!wrapBuffer.end()) { + wrapBuffer.put(outBuffer); + if (outBuffer.end() && !fillBuffer()) { + break; + } + } + return outBuffer.position() - off; + } + + private boolean fillBuffer() throws TIOException { + if (eof) { + return false; + } + int i = 0; + while (!outBuffer.end()) { + outData[i++] = outBuffer.get(); + } + outBuffer.rewind(i); + while (outBuffer.available() > 4) { + if (inBuffer.available() < 8 && !fillReadBuffer()) { + eof = true; + break; + } + charset.decode(inBuffer, outBuffer); + } + return true; + } + + private boolean fillReadBuffer() throws TIOException { + if (streamEof) { + return false; + } + int off = 0; + while (!inBuffer.end()) { + inData[off] = inBuffer.get(); + } + inBuffer.rewind(0); + while (off < inData.length) { + int bytesRead = stream.read(inData, off, inData.length - off); + if (bytesRead == -1) { + streamEof = true; + inBuffer = new ByteBuffer(inData, 0, inBuffer.position()); + break; + } else { + off += bytesRead; + } + } + return true; + } + + @Override + public boolean ready() throws TIOException { + return !outBuffer.end() || inBuffer.end(); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TReader.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TReader.java new file mode 100644 index 000000000..7d028ba89 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TReader.java @@ -0,0 +1,75 @@ +/* + * 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.TMath; +import org.teavm.classlib.java.lang.TObject; + +/** + * + * @author Alexey Andreev + */ +public abstract class TReader implements TCloseable { + protected TObject lock; + + protected TReader() { + this(new TObject()); + } + + protected TReader(TObject lock) { + this.lock = lock; + } + + public int read() throws TIOException { + char[] buf = new char[1]; + return read(buf) >= 0 ? buf[0] : -1; + } + + public int read(char[] cbuf) throws TIOException { + return read(cbuf, 0, cbuf.length); + } + + public abstract int read(char[] cbuf, int off, int len) throws TIOException; + + public long skip(long n) throws TIOException { + char[] buffer = new char[1024]; + long skipped = 0; + while (skipped < n) { + int charsRead = read(buffer, 0, (int)TMath.min(n, buffer.length)); + if (charsRead < 0) { + break; + } + skipped += charsRead; + } + return skipped; + } + + public boolean ready() throws TIOException { + return true; + } + + public boolean markSupported() { + return false; + } + + public void mark(@SuppressWarnings("unused") int readAheadLimit) throws TIOException { + throw new TIOException(); + } + + public void reset() throws TIOException { + throw new TIOException(); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java index cfdc08630..4b34b6b36 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TMath.java @@ -30,4 +30,12 @@ public final class TMath extends TObject { public static int max(int a, int b) { return a > b ? a : b; } + + public static long min(long a, long b) { + return a < b ? a : b; + } + + public static long max(long a, long b) { + return a > b ? a : b; + } } diff --git a/teavm-html4j/src/test/java/org/teavm/html4j/test/KnockoutFXTest.java b/teavm-html4j/src/test/java/org/teavm/html4j/test/KnockoutFXTest.java index 38d342969..da4212977 100644 --- a/teavm-html4j/src/test/java/org/teavm/html4j/test/KnockoutFXTest.java +++ b/teavm-html4j/src/test/java/org/teavm/html4j/test/KnockoutFXTest.java @@ -54,7 +54,9 @@ import net.java.html.BrwsrCtx; import net.java.html.js.JavaScriptBody; import org.apidesign.html.boot.spi.Fn; import org.apidesign.html.context.spi.Contexts; +import org.apidesign.html.json.spi.Transfer; import org.apidesign.html.json.tck.KnockoutTCK; +import org.netbeans.html.ko4j.KO4J; import org.testng.Assert; /** @@ -93,8 +95,10 @@ public final class KnockoutFXTest extends KnockoutTCK { @Override public BrwsrCtx createContext() { - Contexts.Builder cb = Contexts.newBuilder(); - return cb.build(); + KO4J ko4j = new KO4J(); + return Contexts.newBuilder() + .register(Transfer.class, ko4j.transfer(), 1) + .build(); } @Override