diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBuffer.java new file mode 100644 index 000000000..5612a698e --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBuffer.java @@ -0,0 +1,197 @@ +/* + * 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 + */ +public abstract class TIntBuffer extends TBuffer implements Comparable { + int start; + int[] array; + + TIntBuffer(int start, int capacity, int[] array, int position, int limit) { + super(capacity); + this.start = start; + this.array = array; + this.position = position; + this.limit = limit; + } + + public static TIntBuffer allocate(int capacity) { + if (capacity < 0) { + throw new IllegalArgumentException("Capacity is negative: " + capacity); + } + return new TIntBufferImpl(capacity); + } + + public static TIntBuffer wrap(int[] array, int offset, int length) { + return new TIntBufferImpl(0, array.length, array, offset, offset + length, false); + } + + public static TIntBuffer wrap(int[] array) { + return wrap(array, 0, array.length); + } + + public abstract TIntBuffer slice(); + + public abstract TIntBuffer duplicate(); + + public abstract TIntBuffer asReadOnlyBuffer(); + + public abstract int get(); + + public abstract TIntBuffer put(int b); + + public abstract int get(int index); + + public abstract TIntBuffer put(int index, int b); + + public TIntBuffer get(int[] dst, int offset, int length) { + if (offset < 0 || offset >= dst.length) { + throw new IndexOutOfBoundsException("Offset " + offset + " is outside of range [0;" + dst.length + ")"); + } + if (offset + length > dst.length) { + throw new IndexOutOfBoundsException("The last int in dst " + (offset + length) + " is outside " + + "of array of size " + dst.length); + } + if (remaining() < length) { + throw new TBufferUnderflowException(); + } + if (length < 0) { + throw new IndexOutOfBoundsException("Length " + length + " must be non-negative"); + } + int pos = position + start; + for (int i = 0; i < length; ++i) { + dst[offset++] = array[pos++]; + } + position += length; + return this; + } + + public TIntBuffer get(int[] dst) { + return get(dst, 0, dst.length); + } + + public TIntBuffer put(TIntBuffer src) { + return put(src.array, src.start + src.position, src.remaining()); + } + + public TIntBuffer put(int[] src, int offset, int length) { + if (isReadOnly()) { + throw new TReadOnlyBufferException(); + } + if (remaining() < length) { + throw new TBufferOverflowException(); + } + if (offset < 0 || offset >= src.length) { + throw new IndexOutOfBoundsException("Offset " + offset + " is outside of range [0;" + src.length + ")"); + } + if (offset + length > src.length) { + throw new IndexOutOfBoundsException("The last int in src " + (offset + length) + " is outside " + + "of array of size " + src.length); + } + if (length < 0) { + throw new IndexOutOfBoundsException("Length " + length + " must be non-negative"); + } + int pos = position + start; + for (int i = 0; i < length; ++i) { + array[pos++] = src[offset++]; + } + position += length; + return this; + } + + public final TIntBuffer put(int[] src) { + return put(src, 0, src.length); + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public final int[] array() { + return array; + } + + @Override + public int arrayOffset() { + return start; + } + + public abstract TIntBuffer compact(); + + @Override + public abstract boolean isDirect(); + + @Override + public String toString() { + return "[IntBuffer position=" + position + ", limit=" + limit + ", capacity=" + capacity + ", mark " + + (mark >= 0 ? " at " + mark : " is not set") + "]"; + } + + @Override + public int hashCode() { + int hashCode = 0; + int pos = position + start; + for (int i = position; i < limit; ++i) { + hashCode = 31 * hashCode + array[pos++]; + } + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TIntBuffer)) { + return false; + } + TIntBuffer other = (TIntBuffer)obj; + int sz = remaining(); + if (sz != other.remaining()) { + return false; + } + int a = position + start; + int b = other.position + other.start; + for (int i = 0; i < sz; ++i) { + if (array[a++] != other.array[b++]) { + return false; + } + } + return true; + } + + @Override + public int compareTo(TIntBuffer other) { + if (this == other) { + return 0; + } + int sz = Math.min(remaining(), other.remaining()); + int a = position + start; + int b = other.position + other.start; + for (int i = 0; i < sz; ++i) { + int r = Integer.compare(array[a++], other.array[b++]); + if (r != 0) { + return r; + } + } + return Integer.compare(remaining(), other.remaining()); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferImpl.java new file mode 100644 index 000000000..f970eae62 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferImpl.java @@ -0,0 +1,117 @@ +/* + * 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 TIntBufferImpl extends TIntBuffer { + private boolean readOnly; + + public TIntBufferImpl(int capacity) { + this(0, capacity, new int[capacity], 0, capacity, false); + } + + public TIntBufferImpl(int start, int capacity, int[] array, int position, int limit, boolean readOnly) { + super(start, capacity, array, position, limit); + this.readOnly = readOnly; + } + + @Override + public TIntBuffer slice() { + return new TIntBufferImpl(position, limit - position, array, 0, limit - position, readOnly); + } + + @Override + public TIntBuffer duplicate() { + return new TIntBufferImpl(start, capacity, array, position, limit, readOnly); + } + + @Override + public TIntBuffer asReadOnlyBuffer() { + return new TIntBufferImpl(start, capacity, array, position, limit, true); + } + + @Override + public int get() { + if (position >= limit) { + throw new TBufferUnderflowException(); + } + return array[start + position++]; + } + + @Override + public TIntBuffer put(int b) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position >= limit) { + throw new TBufferOverflowException(); + } + array[start + position++] = b; + return this; + } + + @Override + public int get(int index) { + if (index < 0 || index >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")"); + } + return array[start + index]; + } + + @Override + public TIntBuffer put(int index, int b) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (index < 0 || index >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")"); + } + array[start + index] = b; + return this; + } + + @Override + public TIntBuffer compact() { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position > 0) { + int sz = remaining(); + int dst = start; + int src = start + position; + for (int i = 0; i < sz; ++i) { + array[dst++] = array[src++]; + } + position = sz; + } + limit = capacity; + mark = -1; + return this; + } + + @Override + public boolean isDirect() { + return false; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBuffer.java new file mode 100644 index 000000000..5a1940713 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBuffer.java @@ -0,0 +1,197 @@ +/* + * 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 + */ +public abstract class TShortBuffer extends TBuffer implements Comparable { + int start; + short[] array; + + TShortBuffer(int start, int capacity, short[] array, int position, int limit) { + super(capacity); + this.start = start; + this.array = array; + this.position = position; + this.limit = limit; + } + + public static TShortBuffer allocate(int capacity) { + if (capacity < 0) { + throw new IllegalArgumentException("Capacity is negative: " + capacity); + } + return new TShortBufferImpl(capacity); + } + + public static TShortBuffer wrap(short[] array, int offset, int length) { + return new TShortBufferImpl(0, array.length, array, offset, offset + length, false); + } + + public static TShortBuffer wrap(short[] array) { + return wrap(array, 0, array.length); + } + + public abstract TShortBuffer slice(); + + public abstract TShortBuffer duplicate(); + + public abstract TShortBuffer asReadOnlyBuffer(); + + public abstract short get(); + + public abstract TShortBuffer put(short b); + + public abstract short get(int index); + + public abstract TShortBuffer put(int index, short b); + + public TShortBuffer get(short[] dst, int offset, int length) { + if (offset < 0 || offset >= dst.length) { + throw new IndexOutOfBoundsException("Offset " + offset + " is outside of range [0;" + dst.length + ")"); + } + if (offset + length > dst.length) { + throw new IndexOutOfBoundsException("The last short in dst " + (offset + length) + " is outside " + + "of array of size " + dst.length); + } + if (remaining() < length) { + throw new TBufferUnderflowException(); + } + if (length < 0) { + throw new IndexOutOfBoundsException("Length " + length + " must be non-negative"); + } + int pos = position + start; + for (int i = 0; i < length; ++i) { + dst[offset++] = array[pos++]; + } + position += length; + return this; + } + + public TShortBuffer get(short[] dst) { + return get(dst, 0, dst.length); + } + + public TShortBuffer put(TShortBuffer src) { + return put(src.array, src.start + src.position, src.remaining()); + } + + public TShortBuffer put(short[] src, int offset, int length) { + if (isReadOnly()) { + throw new TReadOnlyBufferException(); + } + if (remaining() < length) { + throw new TBufferOverflowException(); + } + if (offset < 0 || offset >= src.length) { + throw new IndexOutOfBoundsException("Offset " + offset + " is outside of range [0;" + src.length + ")"); + } + if (offset + length > src.length) { + throw new IndexOutOfBoundsException("The last short in src " + (offset + length) + " is outside " + + "of array of size " + src.length); + } + if (length < 0) { + throw new IndexOutOfBoundsException("Length " + length + " must be non-negative"); + } + int pos = position + start; + for (int i = 0; i < length; ++i) { + array[pos++] = src[offset++]; + } + position += length; + return this; + } + + public final TShortBuffer put(short[] src) { + return put(src, 0, src.length); + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public final short[] array() { + return array; + } + + @Override + public int arrayOffset() { + return start; + } + + public abstract TShortBuffer compact(); + + @Override + public abstract boolean isDirect(); + + @Override + public String toString() { + return "[ShortBuffer position=" + position + ", limit=" + limit + ", capacity=" + capacity + ", mark " + + (mark >= 0 ? " at " + mark : " is not set") + "]"; + } + + @Override + public int hashCode() { + int hashCode = 0; + int pos = position + start; + for (int i = position; i < limit; ++i) { + hashCode = 31 * hashCode + array[pos++]; + } + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TShortBuffer)) { + return false; + } + TShortBuffer other = (TShortBuffer)obj; + int sz = remaining(); + if (sz != other.remaining()) { + return false; + } + int a = position + start; + int b = other.position + other.start; + for (int i = 0; i < sz; ++i) { + if (array[a++] != other.array[b++]) { + return false; + } + } + return true; + } + + @Override + public int compareTo(TShortBuffer other) { + if (this == other) { + return 0; + } + int sz = Math.min(remaining(), other.remaining()); + int a = position + start; + int b = other.position + other.start; + for (int i = 0; i < sz; ++i) { + int r = Short.compare(array[a++], other.array[b++]); + if (r != 0) { + return r; + } + } + return Integer.compare(remaining(), other.remaining()); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferImpl.java new file mode 100644 index 000000000..a31506f9c --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferImpl.java @@ -0,0 +1,117 @@ +/* + * 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 TShortBufferImpl extends TShortBuffer { + private boolean readOnly; + + public TShortBufferImpl(int capacity) { + this(0, capacity, new short[capacity], 0, capacity, false); + } + + public TShortBufferImpl(int start, int capacity, short[] array, int position, int limit, boolean readOnly) { + super(start, capacity, array, position, limit); + this.readOnly = readOnly; + } + + @Override + public TShortBuffer slice() { + return new TShortBufferImpl(position, limit - position, array, 0, limit - position, readOnly); + } + + @Override + public TShortBuffer duplicate() { + return new TShortBufferImpl(start, capacity, array, position, limit, readOnly); + } + + @Override + public TShortBuffer asReadOnlyBuffer() { + return new TShortBufferImpl(start, capacity, array, position, limit, true); + } + + @Override + public short get() { + if (position >= limit) { + throw new TBufferUnderflowException(); + } + return array[start + position++]; + } + + @Override + public TShortBuffer put(short b) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position >= limit) { + throw new TBufferOverflowException(); + } + array[start + position++] = b; + return this; + } + + @Override + public short get(int index) { + if (index < 0 || index >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")"); + } + return array[start + index]; + } + + @Override + public TShortBuffer put(int index, short b) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (index < 0 || index >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")"); + } + array[start + index] = b; + return this; + } + + @Override + public TShortBuffer compact() { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position > 0) { + int sz = remaining(); + int dst = start; + int src = start + position; + for (int i = 0; i < sz; ++i) { + array[dst++] = array[src++]; + } + position = sz; + } + limit = capacity; + mark = -1; + return this; + } + + @Override + public boolean isDirect() { + return false; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } +} diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/IntBufferTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/IntBufferTest.java new file mode 100644 index 000000000..609ceab77 --- /dev/null +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/IntBufferTest.java @@ -0,0 +1,370 @@ +/* + * 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; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import java.nio.*; +import org.junit.Test; + +/** + * + * @author Alexey Andreev + */ +public class IntBufferTest { + @Test + public void allocatesSimple() { + IntBuffer buffer = IntBuffer.allocate(100); + assertThat(buffer.isDirect(), is(false)); + assertThat(buffer.isReadOnly(), is(false)); + assertThat(buffer.hasArray(), is(true)); + assertThat(buffer.capacity(), is(100)); + assertThat(buffer.position(), is(0)); + assertThat(buffer.limit(), is(100)); + try { + buffer.reset(); + fail("Mark is expected to be undefined"); + } catch (InvalidMarkException e) { + // ok + } + } + + @Test(expected = IllegalArgumentException.class) + public void errorIfAllocatingBufferOfNegativeSize() { + IntBuffer.allocate(-1); + } + + @Test + public void wrapsArray() { + int[] array = new int[100]; + IntBuffer buffer = IntBuffer.wrap(array, 10, 70); + assertThat(buffer.isDirect(), is(false)); + assertThat(buffer.isReadOnly(), is(false)); + assertThat(buffer.hasArray(), is(true)); + assertThat(buffer.array(), is(array)); + assertThat(buffer.arrayOffset(), is(0)); + assertThat(buffer.capacity(), is(100)); + assertThat(buffer.position(), is(10)); + assertThat(buffer.limit(), is(80)); + try { + buffer.reset(); + fail("Mark is expected to be undefined"); + } catch (InvalidMarkException e) { + // ok + } + array[0] = 23; + assertThat(buffer.get(0), is(23)); + buffer.put(1, 24); + assertThat(array[1], is(24)); + } + + @Test + public void errorWhenWrappingWithWrongParameters() { + int[] array = new int[100]; + try { + IntBuffer.wrap(array, -1, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + IntBuffer.wrap(array, 101, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + IntBuffer.wrap(array, 98, 3); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + IntBuffer.wrap(array, 98, -1); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void wrapsArrayWithoutOffset() { + int[] array = new int[100]; + IntBuffer buffer = IntBuffer.wrap(array); + assertThat(buffer.position(), is(0)); + assertThat(buffer.limit(), is(100)); + } + + @Test + public void createsSlice() { + IntBuffer buffer = IntBuffer.allocate(100); + buffer.put(new int[60]); + buffer.flip(); + buffer.put(new int[15]); + IntBuffer slice = buffer.slice(); + assertThat(slice.array(), is(buffer.array())); + assertThat(slice.position(), is(0)); + assertThat(slice.capacity(), is(45)); + assertThat(slice.limit(), is(45)); + assertThat(slice.isDirect(), is(false)); + assertThat(slice.isReadOnly(), is(false)); + slice.put(3, 23); + assertThat(buffer.get(18), is(23)); + slice.put(24); + assertThat(buffer.get(15), is(24)); + buffer.put(16, 25); + assertThat(slice.get(1), is(25)); + } + + @Test + public void slicePropertiesSameWithOriginal() { + IntBuffer buffer = IntBuffer.allocate(100).asReadOnlyBuffer().slice(); + assertThat(buffer.isReadOnly(), is(true)); + } + + @Test + public void createsDuplicate() { + IntBuffer buffer = IntBuffer.allocate(100); + buffer.put(new int[60]); + buffer.flip(); + buffer.put(new int[15]); + IntBuffer duplicate = buffer.duplicate(); + assertThat(duplicate.array(), is(buffer.array())); + assertThat(duplicate.position(), is(15)); + assertThat(duplicate.capacity(), is(100)); + assertThat(duplicate.limit(), is(60)); + assertThat(duplicate.isDirect(), is(false)); + assertThat(duplicate.isReadOnly(), is(false)); + duplicate.put(3, 23); + assertThat(buffer.get(3), is(23)); + duplicate.put(24); + assertThat(buffer.get(15), is(24)); + buffer.put(1, 25); + assertThat(duplicate.get(1), is(25)); + assertThat(duplicate.array(), is(sameInstance(buffer.array()))); + } + + @Test + public void getsInt() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + assertThat(buffer.get(), is(2)); + assertThat(buffer.get(), is(3)); + buffer = buffer.slice(); + assertThat(buffer.get(), is(5)); + assertThat(buffer.get(), is(7)); + } + + @Test + public void gettingIntFromEmptyBufferCausesError() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.limit(2); + buffer.get(); + buffer.get(); + try { + buffer.get(); + fail("Should have thrown error"); + } catch (BufferUnderflowException e) { + // ok + } + } + + @Test + public void putsInt() { + int[] array = new int[4]; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.put(2).put(3).put(5).put(7); + assertThat(array, is(new int[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingIntToEmptyBufferCausesError() { + int[] array = new int[4]; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.limit(2); + buffer.put(2).put(3); + try { + buffer.put(5); + fail("Should have thrown error"); + } catch (BufferOverflowException e) { + assertThat(array[2], is(0)); + } + } + + @Test(expected = ReadOnlyBufferException.class) + public void puttingIntToReadOnlyBufferCausesError() { + int[] array = new int[4]; + IntBuffer buffer = IntBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(2); + } + + @Test + public void getsIntFromGivenLocation() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + assertThat(buffer.get(0), is(2)); + assertThat(buffer.get(1), is(3)); + buffer.get(); + buffer = buffer.slice(); + assertThat(buffer.get(1), is(5)); + assertThat(buffer.get(2), is(7)); + } + + @Test + public void gettingIntFromWrongLocationCausesError() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.limit(3); + try { + buffer.get(-1); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + buffer.get(3); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void putsIntToGivenLocation() { + int[] array = new int[4]; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.put(0, 2); + buffer.put(1, 3); + buffer.get(); + buffer = buffer.slice(); + buffer.put(1, 5); + buffer.put(2, 7); + assertThat(array, is(new int[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingIntToWrongLocationCausesError() { + int[] array = new int[4]; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.limit(3); + try { + buffer.put(-1, 2); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + buffer.put(3, 2); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test(expected = ReadOnlyBufferException.class) + public void puttingIntToGivenLocationOfReadOnlyBufferCausesError() { + int[] array = new int[4]; + IntBuffer buffer = IntBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(0, 2); + } + + @Test + public void getsInts() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.get(); + int[] receiver = new int[2]; + buffer.get(receiver, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(receiver, is(new int[] { 3, 5 })); + } + + @Test + public void gettingIntsFromEmptyBufferCausesError() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.limit(3); + int[] receiver = new int[4]; + try { + buffer.get(receiver, 0, 4); + fail("Error expected"); + } catch (BufferUnderflowException e) { + assertThat(receiver, is(new int[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void gettingIntsWithIllegalArgumentsCausesError() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + int[] receiver = new int[4]; + try { + buffer.get(receiver, 0, 5); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new int[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, -1, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new int[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, 6, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new int[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void putsInts() { + int[] array = new int[4]; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.get(); + int[] data = { 2, 3 }; + buffer.put(data, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(array, is(new int[] {0, 2, 3, 0 })); + } + + @Test + public void compacts() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.get(); + buffer.mark(); + buffer.compact(); + assertThat(array, is(new int[] { 3, 5, 7, 7 })); + assertThat(buffer.position(), is(3)); + assertThat(buffer.limit(), is(4)); + assertThat(buffer.capacity(), is(4)); + try { + buffer.reset(); + fail("Exception expected"); + } catch (InvalidMarkException e) { + // ok + } + } + + @Test + public void marksPosition() { + int[] array = { 2, 3, 5, 7 }; + IntBuffer buffer = IntBuffer.wrap(array); + buffer.position(1); + buffer.mark(); + buffer.position(2); + buffer.reset(); + assertThat(buffer.position(), is(1)); + } +} diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/ShortBufferTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/ShortBufferTest.java new file mode 100644 index 000000000..66bf0521c --- /dev/null +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/ShortBufferTest.java @@ -0,0 +1,354 @@ +package org.teavm.classlib.java.nio; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import java.nio.*; +import org.junit.Test; + +/** + * + * @author Alexey Andreev + */ +public class ShortBufferTest { + @Test + public void allocatesSimple() { + ShortBuffer buffer = ShortBuffer.allocate(100); + assertThat(buffer.isDirect(), is(false)); + assertThat(buffer.isReadOnly(), is(false)); + assertThat(buffer.hasArray(), is(true)); + assertThat(buffer.capacity(), is(100)); + assertThat(buffer.position(), is(0)); + assertThat(buffer.limit(), is(100)); + try { + buffer.reset(); + fail("Mark is expected to be undefined"); + } catch (InvalidMarkException e) { + // ok + } + } + + @Test(expected = IllegalArgumentException.class) + public void errorIfAllocatingBufferOfNegativeSize() { + ShortBuffer.allocate(-1); + } + + @Test + public void wrapsArray() { + short[] array = new short[100]; + ShortBuffer buffer = ShortBuffer.wrap(array, 10, 70); + assertThat(buffer.isDirect(), is(false)); + assertThat(buffer.isReadOnly(), is(false)); + assertThat(buffer.hasArray(), is(true)); + assertThat(buffer.array(), is(array)); + assertThat(buffer.arrayOffset(), is(0)); + assertThat(buffer.capacity(), is(100)); + assertThat(buffer.position(), is(10)); + assertThat(buffer.limit(), is(80)); + try { + buffer.reset(); + fail("Mark is expected to be undefined"); + } catch (InvalidMarkException e) { + // ok + } + array[0] = 23; + assertThat(buffer.get(0), is((short)23)); + buffer.put(1, (short)24); + assertThat(array[1], is((short)24)); + } + + @Test + public void errorWhenWrappingWithWrongParameters() { + short[] array = new short[100]; + try { + ShortBuffer.wrap(array, -1, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + ShortBuffer.wrap(array, 101, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + ShortBuffer.wrap(array, 98, 3); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + ShortBuffer.wrap(array, 98, -1); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void wrapsArrayWithoutOffset() { + short[] array = new short[100]; + ShortBuffer buffer = ShortBuffer.wrap(array); + assertThat(buffer.position(), is(0)); + assertThat(buffer.limit(), is(100)); + } + + @Test + public void createsSlice() { + ShortBuffer buffer = ShortBuffer.allocate(100); + buffer.put(new short[60]); + buffer.flip(); + buffer.put(new short[15]); + ShortBuffer slice = buffer.slice(); + assertThat(slice.array(), is(buffer.array())); + assertThat(slice.position(), is(0)); + assertThat(slice.capacity(), is(45)); + assertThat(slice.limit(), is(45)); + assertThat(slice.isDirect(), is(false)); + assertThat(slice.isReadOnly(), is(false)); + slice.put(3, (short)23); + assertThat(buffer.get(18), is((short)23)); + slice.put((short)24); + assertThat(buffer.get(15), is((short)24)); + buffer.put(16, (short)25); + assertThat(slice.get(1), is((short)25)); + } + + @Test + public void slicePropertiesSameWithOriginal() { + ShortBuffer buffer = ShortBuffer.allocate(100).asReadOnlyBuffer().slice(); + assertThat(buffer.isReadOnly(), is(true)); + } + + @Test + public void createsDuplicate() { + ShortBuffer buffer = ShortBuffer.allocate(100); + buffer.put(new short[60]); + buffer.flip(); + buffer.put(new short[15]); + ShortBuffer duplicate = buffer.duplicate(); + assertThat(duplicate.array(), is(buffer.array())); + assertThat(duplicate.position(), is(15)); + assertThat(duplicate.capacity(), is(100)); + assertThat(duplicate.limit(), is(60)); + assertThat(duplicate.isDirect(), is(false)); + assertThat(duplicate.isReadOnly(), is(false)); + duplicate.put(3, (short)23); + assertThat(buffer.get(3), is((short)23)); + duplicate.put((short)24); + assertThat(buffer.get(15), is((short)24)); + buffer.put(1, (short)25); + assertThat(duplicate.get(1), is((short)25)); + assertThat(duplicate.array(), is(sameInstance(buffer.array()))); + } + + @Test + public void getsShort() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + assertThat(buffer.get(), is((short)2)); + assertThat(buffer.get(), is((short)3)); + buffer = buffer.slice(); + assertThat(buffer.get(), is((short)5)); + assertThat(buffer.get(), is((short)7)); + } + + @Test + public void gettingShortFromEmptyBufferCausesError() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.limit(2); + buffer.get(); + buffer.get(); + try { + buffer.get(); + fail("Should have thrown error"); + } catch (BufferUnderflowException e) { + // ok + } + } + + @Test + public void putsShort() { + short[] array = new short[4]; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.put((short)2).put((short)3).put((short)5).put((short)7); + assertThat(array, is(new short[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingShortToEmptyBufferCausesError() { + short[] array = new short[4]; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.limit(2); + buffer.put((short)2).put((short)3); + try { + buffer.put((short)5); + fail("Should have thrown error"); + } catch (BufferOverflowException e) { + assertThat(array[2], is((short)0)); + } + } + + @Test(expected = ReadOnlyBufferException.class) + public void puttingShortToReadOnlyBufferCausesError() { + short[] array = new short[4]; + ShortBuffer buffer = ShortBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put((short)2); + } + + @Test + public void getsShortFromGivenLocation() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + assertThat(buffer.get(0), is((short)2)); + assertThat(buffer.get(1), is((short)3)); + buffer.get(); + buffer = buffer.slice(); + assertThat(buffer.get(1), is((short)5)); + assertThat(buffer.get(2), is((short)7)); + } + + @Test + public void gettingShortFromWrongLocationCausesError() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.limit(3); + try { + buffer.get(-1); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + buffer.get(3); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void putsShortToGivenLocation() { + short[] array = new short[4]; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.put(0, (short)2); + buffer.put(1, (short)3); + buffer.get(); + buffer = buffer.slice(); + buffer.put(1, (short)5); + buffer.put(2, (short)7); + assertThat(array, is(new short[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingShortToWrongLocationCausesError() { + short[] array = new short[4]; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.limit(3); + try { + buffer.put(-1, (short)2); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + buffer.put(3, (short)2); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test(expected = ReadOnlyBufferException.class) + public void puttingShortToGivenLocationOfReadOnlyBufferCausesError() { + short[] array = new short[4]; + ShortBuffer buffer = ShortBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(0, (short)2); + } + + @Test + public void getsShorts() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.get(); + short[] receiver = new short[2]; + buffer.get(receiver, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(receiver, is(new short[] { 3, 5 })); + } + + @Test + public void gettingShortsFromEmptyBufferCausesError() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.limit(3); + short[] receiver = new short[4]; + try { + buffer.get(receiver, 0, 4); + fail("Error expected"); + } catch (BufferUnderflowException e) { + assertThat(receiver, is(new short[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void gettingShortsWithIllegalArgumentsCausesError() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + short[] receiver = new short[4]; + try { + buffer.get(receiver, 0, 5); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new short[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, -1, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new short[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, 6, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new short[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void putsShorts() { + short[] array = new short[4]; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.get(); + short[] data = { 2, 3 }; + buffer.put(data, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(array, is(new short[] {0, 2, 3, 0 })); + } + + @Test + public void compacts() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.get(); + buffer.mark(); + buffer.compact(); + assertThat(array, is(new short[] { 3, 5, 7, 7 })); + assertThat(buffer.position(), is(3)); + assertThat(buffer.limit(), is(4)); + assertThat(buffer.capacity(), is(4)); + try { + buffer.reset(); + fail("Exception expected"); + } catch (InvalidMarkException e) { + // ok + } + } + + @Test + public void marksPosition() { + short[] array = { 2, 3, 5, 7 }; + ShortBuffer buffer = ShortBuffer.wrap(array); + buffer.position(1); + buffer.mark(); + buffer.position(2); + buffer.reset(); + assertThat(buffer.position(), is(1)); + } +}