diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBuffer.java new file mode 100644 index 000000000..ff5c81074 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBuffer.java @@ -0,0 +1,198 @@ +/* + * 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 TDoubleBuffer extends TBuffer implements Comparable { + int start; + double[] array; + + TDoubleBuffer(int start, int capacity, double[] array, int position, int limit) { + super(capacity); + this.start = start; + this.array = array; + this.position = position; + this.limit = limit; + } + + public static TDoubleBuffer allocate(int capacity) { + if (capacity < 0) { + throw new IllegalArgumentException("Capacity is negative: " + capacity); + } + return new TDoubleBufferImpl(capacity); + } + + public static TDoubleBuffer wrap(double[] array, int offset, int length) { + return new TDoubleBufferImpl(0, array.length, array, offset, offset + length, false); + } + + public static TDoubleBuffer wrap(double[] array) { + return wrap(array, 0, array.length); + } + + public abstract TDoubleBuffer slice(); + + public abstract TDoubleBuffer duplicate(); + + public abstract TDoubleBuffer asReadOnlyBuffer(); + + public abstract double get(); + + public abstract TDoubleBuffer put(double b); + + public abstract double get(int index); + + public abstract TDoubleBuffer put(int index, double b); + + public TDoubleBuffer get(double[] 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 double 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 TDoubleBuffer get(double[] dst) { + return get(dst, 0, dst.length); + } + + public TDoubleBuffer put(TDoubleBuffer src) { + return put(src.array, src.start + src.position, src.remaining()); + } + + public TDoubleBuffer put(double[] 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 double 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 TDoubleBuffer put(double[] src) { + return put(src, 0, src.length); + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public final double[] array() { + return array; + } + + @Override + public int arrayOffset() { + return start; + } + + public abstract TDoubleBuffer compact(); + + @Override + public abstract boolean isDirect(); + + @Override + public String toString() { + return "[DoubleBuffer 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) { + long e = Double.doubleToLongBits(array[pos++]); + hashCode = 31 * hashCode + (int)e + (int)(e >>> 32); + } + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TDoubleBuffer)) { + return false; + } + TDoubleBuffer other = (TDoubleBuffer)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(TDoubleBuffer 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 = Double.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/TDoubleBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferImpl.java new file mode 100644 index 000000000..977b8ef09 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferImpl.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 TDoubleBufferImpl extends TDoubleBuffer { + private boolean readOnly; + + public TDoubleBufferImpl(int capacity) { + this(0, capacity, new double[capacity], 0, capacity, false); + } + + public TDoubleBufferImpl(int start, int capacity, double[] array, int position, int limit, boolean readOnly) { + super(start, capacity, array, position, limit); + this.readOnly = readOnly; + } + + @Override + public TDoubleBuffer slice() { + return new TDoubleBufferImpl(position, limit - position, array, 0, limit - position, readOnly); + } + + @Override + public TDoubleBuffer duplicate() { + return new TDoubleBufferImpl(start, capacity, array, position, limit, readOnly); + } + + @Override + public TDoubleBuffer asReadOnlyBuffer() { + return new TDoubleBufferImpl(start, capacity, array, position, limit, true); + } + + @Override + public double get() { + if (position >= limit) { + throw new TBufferUnderflowException(); + } + return array[start + position++]; + } + + @Override + public TDoubleBuffer put(double b) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position >= limit) { + throw new TBufferOverflowException(); + } + array[start + position++] = b; + return this; + } + + @Override + public double 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 TDoubleBuffer put(int index, double 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 TDoubleBuffer 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/TFloatBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBuffer.java new file mode 100644 index 000000000..88e909f2d --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBuffer.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 TFloatBuffer extends TBuffer implements Comparable { + int start; + float[] array; + + TFloatBuffer(int start, int capacity, float[] array, int position, int limit) { + super(capacity); + this.start = start; + this.array = array; + this.position = position; + this.limit = limit; + } + + public static TFloatBuffer allocate(int capacity) { + if (capacity < 0) { + throw new IllegalArgumentException("Capacity is negative: " + capacity); + } + return new TFloatBufferImpl(capacity); + } + + public static TFloatBuffer wrap(float[] array, int offset, int length) { + return new TFloatBufferImpl(0, array.length, array, offset, offset + length, false); + } + + public static TFloatBuffer wrap(float[] array) { + return wrap(array, 0, array.length); + } + + public abstract TFloatBuffer slice(); + + public abstract TFloatBuffer duplicate(); + + public abstract TFloatBuffer asReadOnlyBuffer(); + + public abstract float get(); + + public abstract TFloatBuffer put(float b); + + public abstract float get(int index); + + public abstract TFloatBuffer put(int index, float b); + + public TFloatBuffer get(float[] 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 float 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 TFloatBuffer get(float[] dst) { + return get(dst, 0, dst.length); + } + + public TFloatBuffer put(TFloatBuffer src) { + return put(src.array, src.start + src.position, src.remaining()); + } + + public TFloatBuffer put(float[] 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 float 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 TFloatBuffer put(float[] src) { + return put(src, 0, src.length); + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public final float[] array() { + return array; + } + + @Override + public int arrayOffset() { + return start; + } + + public abstract TFloatBuffer compact(); + + @Override + public abstract boolean isDirect(); + + @Override + public String toString() { + return "[FloatBuffer 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 + Float.floatToIntBits(array[pos++]); + } + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TFloatBuffer)) { + return false; + } + TFloatBuffer other = (TFloatBuffer)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(TFloatBuffer 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 = Float.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/TFloatBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferImpl.java new file mode 100644 index 000000000..b333ca9b2 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferImpl.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 TFloatBufferImpl extends TFloatBuffer { + private boolean readOnly; + + public TFloatBufferImpl(int capacity) { + this(0, capacity, new float[capacity], 0, capacity, false); + } + + public TFloatBufferImpl(int start, int capacity, float[] array, int position, int limit, boolean readOnly) { + super(start, capacity, array, position, limit); + this.readOnly = readOnly; + } + + @Override + public TFloatBuffer slice() { + return new TFloatBufferImpl(position, limit - position, array, 0, limit - position, readOnly); + } + + @Override + public TFloatBuffer duplicate() { + return new TFloatBufferImpl(start, capacity, array, position, limit, readOnly); + } + + @Override + public TFloatBuffer asReadOnlyBuffer() { + return new TFloatBufferImpl(start, capacity, array, position, limit, true); + } + + @Override + public float get() { + if (position >= limit) { + throw new TBufferUnderflowException(); + } + return array[start + position++]; + } + + @Override + public TFloatBuffer put(float b) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position >= limit) { + throw new TBufferOverflowException(); + } + array[start + position++] = b; + return this; + } + + @Override + public float 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 TFloatBuffer put(int index, float 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 TFloatBuffer 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/TLongBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBuffer.java new file mode 100644 index 000000000..d0a613e52 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBuffer.java @@ -0,0 +1,198 @@ +/* + * 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 TLongBuffer extends TBuffer implements Comparable { + int start; + long[] array; + + TLongBuffer(int start, int capacity, long[] array, int position, int limit) { + super(capacity); + this.start = start; + this.array = array; + this.position = position; + this.limit = limit; + } + + public static TLongBuffer allocate(int capacity) { + if (capacity < 0) { + throw new IllegalArgumentException("Capacity is negative: " + capacity); + } + return new TLongBufferImpl(capacity); + } + + public static TLongBuffer wrap(long[] array, int offset, int length) { + return new TLongBufferImpl(0, array.length, array, offset, offset + length, false); + } + + public static TLongBuffer wrap(long[] array) { + return wrap(array, 0, array.length); + } + + public abstract TLongBuffer slice(); + + public abstract TLongBuffer duplicate(); + + public abstract TLongBuffer asReadOnlyBuffer(); + + public abstract long get(); + + public abstract TLongBuffer put(long b); + + public abstract long get(int index); + + public abstract TLongBuffer put(int index, long b); + + public TLongBuffer get(long[] 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 long 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 (long i = 0; i < length; ++i) { + dst[offset++] = array[pos++]; + } + position += length; + return this; + } + + public TLongBuffer get(long[] dst) { + return get(dst, 0, dst.length); + } + + public TLongBuffer put(TLongBuffer src) { + return put(src.array, src.start + src.position, src.remaining()); + } + + public TLongBuffer put(long[] 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 long 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 (long i = 0; i < length; ++i) { + array[pos++] = src[offset++]; + } + position += length; + return this; + } + + public final TLongBuffer put(long[] src) { + return put(src, 0, src.length); + } + + @Override + public boolean hasArray() { + return true; + } + + @Override + public final long[] array() { + return array; + } + + @Override + public int arrayOffset() { + return start; + } + + public abstract TLongBuffer compact(); + + @Override + public abstract boolean isDirect(); + + @Override + public String toString() { + return "[LongBuffer 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) { + long e = array[pos++]; + hashCode = 31 * hashCode + (int)e + (int)(e >>> 32); + } + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TLongBuffer)) { + return false; + } + TLongBuffer other = (TLongBuffer)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(TLongBuffer other) { + if (this == other) { + return 0; + } + int sz = Math.min(remaining(), other.remaining()); + int a = position + start; + int b = other.position + other.start; + for (long i = 0; i < sz; ++i) { + int r = Long.compare(array[a++], other.array[b++]); + if (r != 0) { + return r; + } + } + return Long.compare(remaining(), other.remaining()); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferImpl.java new file mode 100644 index 000000000..d705dc281 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferImpl.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 TLongBufferImpl extends TLongBuffer { + private boolean readOnly; + + public TLongBufferImpl(int capacity) { + this(0, capacity, new long[capacity], 0, capacity, false); + } + + public TLongBufferImpl(int start, int capacity, long[] array, int position, int limit, boolean readOnly) { + super(start, capacity, array, position, limit); + this.readOnly = readOnly; + } + + @Override + public TLongBuffer slice() { + return new TLongBufferImpl(position, limit - position, array, 0, limit - position, readOnly); + } + + @Override + public TLongBuffer duplicate() { + return new TLongBufferImpl(start, capacity, array, position, limit, readOnly); + } + + @Override + public TLongBuffer asReadOnlyBuffer() { + return new TLongBufferImpl(start, capacity, array, position, limit, true); + } + + @Override + public long get() { + if (position >= limit) { + throw new TBufferUnderflowException(); + } + return array[start + position++]; + } + + @Override + public TLongBuffer put(long b) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position >= limit) { + throw new TBufferOverflowException(); + } + array[start + position++] = b; + return this; + } + + @Override + public long 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 TLongBuffer put(int index, long 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 TLongBuffer 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/DoubleBufferTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/DoubleBufferTest.java new file mode 100644 index 000000000..7d98f7524 --- /dev/null +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/DoubleBufferTest.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 DoubleBufferTest { + @Test + public void allocatesSimple() { + DoubleBuffer buffer = DoubleBuffer.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() { + DoubleBuffer.allocate(-1); + } + + @Test + public void wrapsArray() { + double[] array = new double[100]; + DoubleBuffer buffer = DoubleBuffer.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((double)23)); + buffer.put(1, 24); + assertThat(array[1], is((double)24)); + } + + @Test + public void errorWhenWrappingWithWrongParameters() { + double[] array = new double[100]; + try { + DoubleBuffer.wrap(array, -1, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + DoubleBuffer.wrap(array, 101, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + DoubleBuffer.wrap(array, 98, 3); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + DoubleBuffer.wrap(array, 98, -1); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void wrapsArrayWithoutOffset() { + double[] array = new double[100]; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + assertThat(buffer.position(), is(0)); + assertThat(buffer.limit(), is(100)); + } + + @Test + public void createsSlice() { + DoubleBuffer buffer = DoubleBuffer.allocate(100); + buffer.put(new double[60]); + buffer.flip(); + buffer.put(new double[15]); + DoubleBuffer 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((double)23)); + slice.put(24); + assertThat(buffer.get(15), is((double)24)); + buffer.put(16, 25); + assertThat(slice.get(1), is((double)25)); + } + + @Test + public void slicePropertiesSameWithOriginal() { + DoubleBuffer buffer = DoubleBuffer.allocate(100).asReadOnlyBuffer().slice(); + assertThat(buffer.isReadOnly(), is(true)); + } + + @Test + public void createsDuplicate() { + DoubleBuffer buffer = DoubleBuffer.allocate(100); + buffer.put(new double[60]); + buffer.flip(); + buffer.put(new double[15]); + DoubleBuffer 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((double)23)); + duplicate.put(24); + assertThat(buffer.get(15), is((double)24)); + buffer.put(1, 25); + assertThat(duplicate.get(1), is((double)25)); + assertThat(duplicate.array(), is(sameInstance(buffer.array()))); + } + + @Test + public void getsDouble() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + assertThat(buffer.get(), is((double)2)); + assertThat(buffer.get(), is((double)3)); + buffer = buffer.slice(); + assertThat(buffer.get(), is((double)5)); + assertThat(buffer.get(), is((double)7)); + } + + @Test + public void gettingDoubleFromEmptyBufferCausesError() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + buffer.limit(2); + buffer.get(); + buffer.get(); + try { + buffer.get(); + fail("Should have thrown error"); + } catch (BufferUnderflowException e) { + // ok + } + } + + @Test + public void putsDouble() { + double[] array = new double[4]; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + buffer.put(2).put(3).put(5).put(7); + assertThat(array, is(new double[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingDoubleToEmptyBufferCausesError() { + double[] array = new double[4]; + DoubleBuffer buffer = DoubleBuffer.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((double)0)); + } + } + + @Test(expected = ReadOnlyBufferException.class) + public void puttingDoubleToReadOnlyBufferCausesError() { + double[] array = new double[4]; + DoubleBuffer buffer = DoubleBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(2); + } + + @Test + public void getsDoubleFromGivenLocation() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + assertThat(buffer.get(0), is((double)2)); + assertThat(buffer.get(1), is((double)3)); + buffer.get(); + buffer = buffer.slice(); + assertThat(buffer.get(1), is((double)5)); + assertThat(buffer.get(2), is((double)7)); + } + + @Test + public void gettingDoubleFromWrongLocationCausesError() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + buffer.limit(3); + try { + buffer.get(-1); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + buffer.get(3); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void putsDoubleToGivenLocation() { + double[] array = new double[4]; + DoubleBuffer buffer = DoubleBuffer.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 double[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingDoubleToWrongLocationCausesError() { + double[] array = new double[4]; + DoubleBuffer buffer = DoubleBuffer.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 puttingDoubleToGivenLocationOfReadOnlyBufferCausesError() { + double[] array = new double[4]; + DoubleBuffer buffer = DoubleBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(0, 2); + } + + @Test + public void getsDoubles() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + buffer.get(); + double[] receiver = new double[2]; + buffer.get(receiver, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(receiver, is(new double[] { 3, 5 })); + } + + @Test + public void gettingDoublesFromEmptyBufferCausesError() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + buffer.limit(3); + double[] receiver = new double[4]; + try { + buffer.get(receiver, 0, 4); + fail("Error expected"); + } catch (BufferUnderflowException e) { + assertThat(receiver, is(new double[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void gettingDoublesWithIllegalArgumentsCausesError() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + double[] receiver = new double[4]; + try { + buffer.get(receiver, 0, 5); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new double[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, -1, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new double[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, 6, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new double[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void putsDoubles() { + double[] array = new double[4]; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + buffer.get(); + double[] data = { 2, 3 }; + buffer.put(data, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(array, is(new double[] {0, 2, 3, 0 })); + } + + @Test + public void compacts() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.wrap(array); + buffer.get(); + buffer.mark(); + buffer.compact(); + assertThat(array, is(new double[] { 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() { + double[] array = { 2, 3, 5, 7 }; + DoubleBuffer buffer = DoubleBuffer.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/FloatBufferTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/FloatBufferTest.java new file mode 100644 index 000000000..5b87b7e57 --- /dev/null +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/FloatBufferTest.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 FloatBufferTest { + @Test + public void allocatesSimple() { + FloatBuffer buffer = FloatBuffer.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() { + FloatBuffer.allocate(-1); + } + + @Test + public void wrapsArray() { + float[] array = new float[100]; + FloatBuffer buffer = FloatBuffer.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((float)23)); + buffer.put(1, 24); + assertThat(array[1], is((float)24)); + } + + @Test + public void errorWhenWrappingWithWrongParameters() { + float[] array = new float[100]; + try { + FloatBuffer.wrap(array, -1, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + FloatBuffer.wrap(array, 101, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + FloatBuffer.wrap(array, 98, 3); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + FloatBuffer.wrap(array, 98, -1); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void wrapsArrayWithoutOffset() { + float[] array = new float[100]; + FloatBuffer buffer = FloatBuffer.wrap(array); + assertThat(buffer.position(), is(0)); + assertThat(buffer.limit(), is(100)); + } + + @Test + public void createsSlice() { + FloatBuffer buffer = FloatBuffer.allocate(100); + buffer.put(new float[60]); + buffer.flip(); + buffer.put(new float[15]); + FloatBuffer 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((float)23)); + slice.put(24); + assertThat(buffer.get(15), is((float)24)); + buffer.put(16, 25); + assertThat(slice.get(1), is((float)25)); + } + + @Test + public void slicePropertiesSameWithOriginal() { + FloatBuffer buffer = FloatBuffer.allocate(100).asReadOnlyBuffer().slice(); + assertThat(buffer.isReadOnly(), is(true)); + } + + @Test + public void createsDuplicate() { + FloatBuffer buffer = FloatBuffer.allocate(100); + buffer.put(new float[60]); + buffer.flip(); + buffer.put(new float[15]); + FloatBuffer 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((float)23)); + duplicate.put(24); + assertThat(buffer.get(15), is((float)24)); + buffer.put(1, 25); + assertThat(duplicate.get(1), is((float)25)); + assertThat(duplicate.array(), is(sameInstance(buffer.array()))); + } + + @Test + public void getsFloat() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + assertThat(buffer.get(), is((float)2)); + assertThat(buffer.get(), is((float)3)); + buffer = buffer.slice(); + assertThat(buffer.get(), is((float)5)); + assertThat(buffer.get(), is((float)7)); + } + + @Test + public void gettingFloatFromEmptyBufferCausesError() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + buffer.limit(2); + buffer.get(); + buffer.get(); + try { + buffer.get(); + fail("Should have thrown error"); + } catch (BufferUnderflowException e) { + // ok + } + } + + @Test + public void putsFloat() { + float[] array = new float[4]; + FloatBuffer buffer = FloatBuffer.wrap(array); + buffer.put(2).put(3).put(5).put(7); + assertThat(array, is(new float[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingFloatToEmptyBufferCausesError() { + float[] array = new float[4]; + FloatBuffer buffer = FloatBuffer.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((float)0)); + } + } + + @Test(expected = ReadOnlyBufferException.class) + public void puttingFloatToReadOnlyBufferCausesError() { + float[] array = new float[4]; + FloatBuffer buffer = FloatBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(2); + } + + @Test + public void getsFloatFromGivenLocation() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + assertThat(buffer.get(0), is((float)2)); + assertThat(buffer.get(1), is((float)3)); + buffer.get(); + buffer = buffer.slice(); + assertThat(buffer.get(1), is((float)5)); + assertThat(buffer.get(2), is((float)7)); + } + + @Test + public void gettingFloatFromWrongLocationCausesError() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + buffer.limit(3); + try { + buffer.get(-1); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + buffer.get(3); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void putsFloatToGivenLocation() { + float[] array = new float[4]; + FloatBuffer buffer = FloatBuffer.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 float[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingFloatToWrongLocationCausesError() { + float[] array = new float[4]; + FloatBuffer buffer = FloatBuffer.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 puttingFloatToGivenLocationOfReadOnlyBufferCausesError() { + float[] array = new float[4]; + FloatBuffer buffer = FloatBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(0, 2); + } + + @Test + public void getsFloats() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + buffer.get(); + float[] receiver = new float[2]; + buffer.get(receiver, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(receiver, is(new float[] { 3, 5 })); + } + + @Test + public void gettingFloatsFromEmptyBufferCausesError() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + buffer.limit(3); + float[] receiver = new float[4]; + try { + buffer.get(receiver, 0, 4); + fail("Error expected"); + } catch (BufferUnderflowException e) { + assertThat(receiver, is(new float[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void gettingFloatsWithIllegalArgumentsCausesError() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + float[] receiver = new float[4]; + try { + buffer.get(receiver, 0, 5); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new float[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, -1, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new float[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, 6, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new float[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void putsFloats() { + float[] array = new float[4]; + FloatBuffer buffer = FloatBuffer.wrap(array); + buffer.get(); + float[] data = { 2, 3 }; + buffer.put(data, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(array, is(new float[] {0, 2, 3, 0 })); + } + + @Test + public void compacts() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.wrap(array); + buffer.get(); + buffer.mark(); + buffer.compact(); + assertThat(array, is(new float[] { 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() { + float[] array = { 2, 3, 5, 7 }; + FloatBuffer buffer = FloatBuffer.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/LongBufferTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/LongBufferTest.java new file mode 100644 index 000000000..57f1b66e9 --- /dev/null +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/LongBufferTest.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 LongBufferTest { + @Test + public void allocatesSimple() { + LongBuffer buffer = LongBuffer.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() { + LongBuffer.allocate(-1); + } + + @Test + public void wrapsArray() { + long[] array = new long[100]; + LongBuffer buffer = LongBuffer.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((long)23)); + buffer.put(1, 24); + assertThat(array[1], is((long)24)); + } + + @Test + public void errorWhenWrappingWithWrongParameters() { + long[] array = new long[100]; + try { + LongBuffer.wrap(array, -1, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + LongBuffer.wrap(array, 101, 10); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + LongBuffer.wrap(array, 98, 3); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + LongBuffer.wrap(array, 98, -1); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void wrapsArrayWithoutOffset() { + long[] array = new long[100]; + LongBuffer buffer = LongBuffer.wrap(array); + assertThat(buffer.position(), is(0)); + assertThat(buffer.limit(), is(100)); + } + + @Test + public void createsSlice() { + LongBuffer buffer = LongBuffer.allocate(100); + buffer.put(new long[60]); + buffer.flip(); + buffer.put(new long[15]); + LongBuffer 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((long)23)); + slice.put(24); + assertThat(buffer.get(15), is((long)24)); + buffer.put(16, 25); + assertThat(slice.get(1), is((long)25)); + } + + @Test + public void slicePropertiesSameWithOriginal() { + LongBuffer buffer = LongBuffer.allocate(100).asReadOnlyBuffer().slice(); + assertThat(buffer.isReadOnly(), is(true)); + } + + @Test + public void createsDuplicate() { + LongBuffer buffer = LongBuffer.allocate(100); + buffer.put(new long[60]); + buffer.flip(); + buffer.put(new long[15]); + LongBuffer 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((long)23)); + duplicate.put(24); + assertThat(buffer.get(15), is((long)24)); + buffer.put(1, 25); + assertThat(duplicate.get(1), is((long)25)); + assertThat(duplicate.array(), is(sameInstance(buffer.array()))); + } + + @Test + public void getsLong() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + assertThat(buffer.get(), is((long)2)); + assertThat(buffer.get(), is((long)3)); + buffer = buffer.slice(); + assertThat(buffer.get(), is((long)5)); + assertThat(buffer.get(), is((long)7)); + } + + @Test + public void gettingLongFromEmptyBufferCausesError() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.limit(2); + buffer.get(); + buffer.get(); + try { + buffer.get(); + fail("Should have thrown error"); + } catch (BufferUnderflowException e) { + // ok + } + } + + @Test + public void putsLong() { + long[] array = new long[4]; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.put(2).put(3).put(5).put(7); + assertThat(array, is(new long[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingLongToEmptyBufferCausesError() { + long[] array = new long[4]; + LongBuffer buffer = LongBuffer.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((long)0)); + } + } + + @Test(expected = ReadOnlyBufferException.class) + public void puttingLongToReadOnlyBufferCausesError() { + long[] array = new long[4]; + LongBuffer buffer = LongBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(2); + } + + @Test + public void getsLongFromGivenLocation() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + assertThat(buffer.get(0), is((long)2)); + assertThat(buffer.get(1), is((long)3)); + buffer.get(); + buffer = buffer.slice(); + assertThat(buffer.get(1), is((long)5)); + assertThat(buffer.get(2), is((long)7)); + } + + @Test + public void gettingLongFromWrongLocationCausesError() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.limit(3); + try { + buffer.get(-1); + } catch (IndexOutOfBoundsException e) { + // ok + } + try { + buffer.get(3); + } catch (IndexOutOfBoundsException e) { + // ok + } + } + + @Test + public void putsLongToGivenLocation() { + long[] array = new long[4]; + LongBuffer buffer = LongBuffer.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 long[] { 2, 3, 5, 7 })); + } + + @Test + public void puttingLongToWrongLocationCausesError() { + long[] array = new long[4]; + LongBuffer buffer = LongBuffer.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 puttingLongToGivenLocationOfReadOnlyBufferCausesError() { + long[] array = new long[4]; + LongBuffer buffer = LongBuffer.wrap(array).asReadOnlyBuffer(); + buffer.put(0, 2); + } + + @Test + public void getsLongs() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.get(); + long[] receiver = new long[2]; + buffer.get(receiver, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(receiver, is(new long[] { 3, 5 })); + } + + @Test + public void gettingLongsFromEmptyBufferCausesError() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.limit(3); + long[] receiver = new long[4]; + try { + buffer.get(receiver, 0, 4); + fail("Error expected"); + } catch (BufferUnderflowException e) { + assertThat(receiver, is(new long[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void gettingLongsWithIllegalArgumentsCausesError() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + long[] receiver = new long[4]; + try { + buffer.get(receiver, 0, 5); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new long[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, -1, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new long[4])); + assertThat(buffer.position(), is(0)); + } + try { + buffer.get(receiver, 6, 3); + } catch (IndexOutOfBoundsException e) { + assertThat(receiver, is(new long[4])); + assertThat(buffer.position(), is(0)); + } + } + + @Test + public void putsLongs() { + long[] array = new long[4]; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.get(); + long[] data = { 2, 3 }; + buffer.put(data, 0, 2); + assertThat(buffer.position(), is(3)); + assertThat(array, is(new long[] {0, 2, 3, 0 })); + } + + @Test + public void compacts() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.get(); + buffer.mark(); + buffer.compact(); + assertThat(array, is(new long[] { 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() { + long[] array = { 2, 3, 5, 7 }; + LongBuffer buffer = LongBuffer.wrap(array); + buffer.position(1); + buffer.mark(); + buffer.position(2); + buffer.reset(); + assertThat(buffer.position(), is(1)); + } +}