diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java index 164c56cbe..7bef817d6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java @@ -198,4 +198,6 @@ public abstract class TByteBuffer extends TBuffer implements TComparable, Appendable, CharSequence, TReadable { - int start; - char[] array; - - TCharBuffer(int start, int capacity, char[] array, int position, int limit) { + TCharBuffer(int capacity, int position, int limit) { super(capacity); - this.start = start; - this.array = array; this.position = position; this.limit = limit; } + abstract char getChar(int index); + + abstract void putChar(int index, char value); + public static TCharBuffer allocate(int capacity) { if (capacity < 0) { throw new IllegalArgumentException("Capacity is negative: " + capacity); } - return new TCharBufferImpl(capacity); + return new TCharBufferOverArray(capacity); } public static TCharBuffer wrap(char[] array, int offset, int length) { - return new TCharBufferImpl(0, array.length, array, offset, offset + length, false); + return new TCharBufferOverArray(0, array.length, array, offset, offset + length, false); } public static TCharBuffer wrap(char[] array) { @@ -62,7 +61,12 @@ public abstract class TCharBuffer extends TBuffer implements Comparable end) { throw new IndexOutOfBoundsException("Start " + start + " must be before end " + end); } - int pos = position + this.start; + int pos = position; while (start < end) { - array[pos++] = src.charAt(start++); + putChar(pos++, src.charAt(start++)); } position += sz; return this; @@ -179,19 +196,25 @@ public abstract class TCharBuffer extends TBuffer implements Comparable */ -class TCharBufferImpl extends TCharBuffer { - private boolean readOnly; - - public TCharBufferImpl(int capacity) { - this(0, capacity, new char[capacity], 0, capacity, false); - } - - public TCharBufferImpl(int start, int capacity, char[] array, int position, int limit, - boolean readOnly) { - super(start, capacity, array, position, limit); - this.readOnly = readOnly; +abstract class TCharBufferImpl extends TCharBuffer { + public TCharBufferImpl(int capacity, int position, int limit) { + super(capacity, position, limit); } @Override public TCharBuffer slice() { - return new TCharBufferImpl(position, limit - position, array, 0, limit - position, readOnly); + return duplicate(position, limit - position, 0, limit - position, isReadOnly()); } @Override public TCharBuffer duplicate() { - return new TCharBufferImpl(start, capacity, array, position, limit, readOnly); + return duplicate(0, capacity, position, limit, isReadOnly()); } @Override public TCharBuffer asReadOnlyBuffer() { - return new TCharBufferImpl(start, capacity, array, position, limit, true); + return duplicate(0, capacity, position, limit, true); } + abstract TCharBuffer duplicate(int start, int capacity, int position, int limit, boolean readOnly); + @Override public char get() { if (position >= limit) { throw new TBufferUnderflowException(); } - return array[start + position++]; + return getChar(position++); } @Override public TCharBuffer put(char c) { - if (readOnly) { + if (isReadOnly()) { throw new TReadOnlyBufferException(); } if (position >= limit) { throw new TBufferOverflowException(); } - array[start + position++] = c; + putChar(position++, c); return this; } @@ -72,32 +66,31 @@ class TCharBufferImpl extends TCharBuffer { if (index < 0 || index >= limit) { throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")"); } - return array[start + index]; + return getChar(index); } @Override public TCharBuffer put(int index, char b) { - if (readOnly) { + if (isReadOnly()) { throw new TReadOnlyBufferException(); } if (index < 0 || index >= limit) { throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")"); } - array[start + index] = b; + putChar(index, b); return this; } @Override public TCharBuffer compact() { - if (readOnly) { + if (isReadOnly()) { throw new TReadOnlyBufferException(); } if (position > 0) { int sz = remaining(); - int dst = start; - int src = start + position; + int src = position; for (int i = 0; i < sz; ++i) { - array[dst++] = array[src++]; + putChar(i, getChar(src++)); } position = sz; } @@ -113,11 +106,13 @@ class TCharBufferImpl extends TCharBuffer { @Override public boolean isReadOnly() { - return readOnly; + return readOnly(); } + abstract boolean readOnly(); + @Override public TCharBuffer subSequence(int start, int end) { - return wrap(array, arrayOffset() + start, end - start); + return duplicate(0, capacity, position + start, position + end, isReadOnly()); } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverArray.java new file mode 100644 index 000000000..b0b179691 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverArray.java @@ -0,0 +1,72 @@ +/* + * 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.nio; + +/** + * + * @author Alexey Andreev + */ +class TCharBufferOverArray extends TCharBufferImpl { + boolean readOnly; + int start; + char[] array; + + public TCharBufferOverArray(int capacity) { + this(0, capacity, new char[capacity], 0, capacity, false); + } + + public TCharBufferOverArray(int start, int capacity, char[] array, int position, int limit, boolean readOnly) { + super(capacity, position, limit); + this.start = start; + this.readOnly = readOnly; + this.array = array; + } + + @Override + TCharBuffer duplicate(int start, int capacity, int position, int limit, boolean readOnly) { + return new TCharBufferOverArray(this.start + start, capacity, array, position, limit, readOnly); + } + + @Override + char getChar(int index) { + return array[index + start]; + } + + @Override + void putChar(int index, char value) { + array[index + start] = value; + } + + @Override + boolean isArrayPresent() { + return true; + } + + @Override + char[] getArray() { + return array; + } + + @Override + int getArrayOffset() { + return start; + } + + @Override + boolean readOnly() { + return readOnly; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBuffer.java new file mode 100644 index 000000000..f68a74094 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBuffer.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.nio; + +/** + * + * @author Alexey Andreev + */ +class TCharBufferOverByteBuffer extends TCharBufferImpl { + private TByteBufferImpl byteByffer; + private TByteOrder byteOrder = TByteOrder.BIG_ENDIAN; + boolean readOnly; + private int start; + + public TCharBufferOverByteBuffer(int start, int capacity, TByteBufferImpl byteBuffer, int position, int limit, + boolean readOnly) { + super(capacity, position, limit); + this.start = start; + this.byteByffer = byteBuffer; + this.readOnly = readOnly; + } + + @Override + TCharBuffer duplicate(int start, int capacity, int position, int limit, boolean readOnly) { + TCharBufferOverByteBuffer result = new TCharBufferOverByteBuffer(this.start + start * 2, capacity, byteByffer, + position, limit, readOnly); + result.byteOrder = byteOrder; + return result; + } + + @Override + char getChar(int index) { + int value; + if (byteOrder == TByteOrder.BIG_ENDIAN) { + value = (byteByffer.array[start + index * 2] << 8) | (byteByffer.array[start + index * 2 + 1]); + } else { + value = (byteByffer.array[start + index * 2 + 1] << 8) | (byteByffer.array[start + index * 2]); + } + return (char)value; + } + + @Override + void putChar(int index, char value) { + if (byteOrder == TByteOrder.BIG_ENDIAN) { + byteByffer.array[start + index * 2] = (byte)(value >> 8); + byteByffer.array[start + index * 2 + 1] = (byte)value; + } else { + byteByffer.array[start + index * 2] = (byte)value; + byteByffer.array[start + index * 2 + 1] = (byte)(value >> 8); + } + } + + @Override + boolean isArrayPresent() { + return false; + } + + @Override + char[] getArray() { + throw new UnsupportedOperationException(); + } + + @Override + int getArrayOffset() { + throw new UnsupportedOperationException(); + } + + @Override + boolean readOnly() { + return readOnly; + } +}