diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java index 8e629405e..ddadfb53a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TByteBuffer.java @@ -209,8 +209,24 @@ public abstract class TByteBuffer extends TBuffer implements TComparable= limit) { + throw new TBufferUnderflowException(); + } + int a = array[start + position] & 0xFF; + int b = array[start + position + 1] & 0xFF; + position += 2; + if (order == TByteOrder.BIG_ENDIAN) { + return (short)((a << 8) | b); + } else { + return (short)((b << 8) | a); + } + } + + @Override + public TByteBuffer putShort(short value) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position + 1 >= limit) { + throw new TBufferOverflowException(); + } + if (order == TByteOrder.BIG_ENDIAN) { + array[start + position++] = (byte)(value >> 8); + array[start + position++] = (byte)value; + } else { + array[start + position++] = (byte)value; + array[start + position++] = (byte)(value >> 8); + } + return this; + } + + @Override + public short getShort(int index) { + if (index < 0 || index + 1 >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + (limit - 1) + ")"); + } + int a = array[start + index] & 0xFF; + int b = array[start + index + 1] & 0xFF; + if (order == TByteOrder.BIG_ENDIAN) { + return (short)((a << 8) | b); + } else { + return (short)((b << 8) | a); + } + } + + @Override + public TByteBuffer putShort(int index, short value) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (index < 0 || index + 1 >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + (limit - 1) + ")"); + } + if (order == TByteOrder.BIG_ENDIAN) { + array[start + index] = (byte)(value >> 8); + array[start + index + 1] = (byte)value; + } else { + array[start + index] = (byte)value; + array[start + index + 1] = (byte)(value >> 8); + } + return this; + } + @Override public TShortBuffer asShortBuffer() { int sz = remaining() / 2; @@ -188,6 +253,83 @@ class TByteBufferImpl extends TByteBuffer { } } + @Override + public int getInt() { + if (position + 3 >= limit) { + throw new TBufferUnderflowException(); + } + int a = array[start + position] & 0xFF; + int b = array[start + position + 1] & 0xFF; + int c = array[start + position + 2] & 0xFF; + int d = array[start + position + 3] & 0xFF; + position += 4; + if (order == TByteOrder.BIG_ENDIAN) { + return (short)((a << 24) | (b << 16) | (c << 8) | d); + } else { + return (short)((d << 24) | (c << 16) | (b << 8) | a); + } + } + + @Override + public TByteBuffer putInt(int value) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position + 3 >= limit) { + throw new TBufferOverflowException(); + } + if (order == TByteOrder.BIG_ENDIAN) { + array[start + position++] = (byte)(value >> 24); + array[start + position++] = (byte)(value >> 16); + array[start + position++] = (byte)(value >> 8); + array[start + position++] = (byte)value; + } else { + array[start + position++] = (byte)value; + array[start + position++] = (byte)(value >> 8); + array[start + position++] = (byte)(value >> 16); + array[start + position++] = (byte)(value >> 24); + } + return this; + } + + @Override + public int getInt(int index) { + if (index < 0 || index + 3 >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + (limit - 3) + ")"); + } + int a = array[start + position] & 0xFF; + int b = array[start + position + 1] & 0xFF; + int c = array[start + position + 2] & 0xFF; + int d = array[start + position + 3] & 0xFF; + if (order == TByteOrder.BIG_ENDIAN) { + return (short)((a << 24) | (b << 16) | (c << 8) | d); + } else { + return (short)((d << 24) | (c << 16) | (b << 8) | a); + } + } + + @Override + public TByteBuffer putInt(int index, int value) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (index < 0 || index + 3 >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + (limit - 3) + ")"); + } + if (order == TByteOrder.BIG_ENDIAN) { + array[start + index] = (byte)(value >> 24); + array[start + index + 1] = (byte)(value >> 16); + array[start + index + 2] = (byte)(value >> 8); + array[start + index + 3] = (byte)value; + } else { + array[start + index] = (byte)value; + array[start + index + 1] = (byte)(value >> 8); + array[start + index + 2] = (byte)(value >> 16); + array[start + index + 3] = (byte)(value >> 24); + } + return this; + } + @Override public TIntBuffer asIntBuffer() { int sz = remaining() / 4; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java index 2d78c4f79..a9d997c56 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java @@ -35,7 +35,7 @@ class TDoubleBufferOverByteBuffer extends TDoubleBufferImpl { @Override TDoubleBuffer duplicate(int start, int capacity, int position, int limit, boolean readOnly) { - TDoubleBufferOverByteBuffer result = new TDoubleBufferOverByteBuffer(this.start + start * 2, capacity, + TDoubleBufferOverByteBuffer result = new TDoubleBufferOverByteBuffer(this.start + start * 8, capacity, byteByffer, position, limit, readOnly); result.byteOrder = byteOrder; return result; diff --git a/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/ByteBufferTest.java b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/ByteBufferTest.java index 9fd2889be..846351a7b 100644 --- a/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/ByteBufferTest.java +++ b/teavm-classlib/src/test/java/org/teavm/classlib/java/nio/ByteBufferTest.java @@ -374,4 +374,128 @@ public class ByteBufferTest { buffer.reset(); assertThat(buffer.position(), is(1)); } + + @Test + public void getsChar() { + byte[] array = { 0, 'A', 0, 'B' }; + ByteBuffer buffer = ByteBuffer.wrap(array); + assertThat(buffer.getChar(), is('A')); + assertThat(buffer.getChar(), is('B')); + try { + buffer.getChar(); + fail("Exception expected"); + } catch (BufferUnderflowException e) { + // expected + } + buffer.position(3); + try { + buffer.getChar(); + fail("Exception expected"); + } catch (BufferUnderflowException e) { + // expected + } + assertThat(buffer.getChar(0), is('A')); + assertThat(buffer.getChar(2), is('B')); + try { + buffer.getChar(3); + fail("Exception expected"); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + @Test + public void putsChar() { + byte[] array = new byte[4]; + ByteBuffer buffer = ByteBuffer.wrap(array); + buffer.putChar('A'); + buffer.putChar('B'); + try { + buffer.putChar('C'); + fail("Exception expected"); + } catch (BufferOverflowException e) { + // expected + } + buffer.position(3); + try { + buffer.putChar('D'); + fail("Exception expected"); + } catch (BufferOverflowException e) { + // expected + } + assertThat(buffer.get(0), is((byte)0)); + assertThat(buffer.get(1), is((byte)'A')); + assertThat(buffer.get(2), is((byte)0)); + assertThat(buffer.get(3), is((byte)'B')); + buffer.putChar(0, 'E'); + assertThat(buffer.get(1), is((byte)'E')); + try { + buffer.putChar(3, 'F'); + fail("Exception expected"); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + @Test + public void getsShort() { + byte[] array = { 0x23, 0x24, 0x25, 0x26 }; + ByteBuffer buffer = ByteBuffer.wrap(array); + assertThat(buffer.getShort(), is((short)0x2324)); + assertThat(buffer.getShort(), is((short)0x2526)); + try { + buffer.getShort(); + fail("Exception expected"); + } catch (BufferUnderflowException e) { + // expected + } + buffer.position(3); + try { + buffer.getShort(); + fail("Exception expected"); + } catch (BufferUnderflowException e) { + // expected + } + assertThat(buffer.getShort(0), is((short)0x2324)); + assertThat(buffer.getShort(2), is((short)0x2526)); + try { + buffer.getShort(3); + fail("Exception expected"); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + @Test + public void putsShort() { + byte[] array = new byte[4]; + ByteBuffer buffer = ByteBuffer.wrap(array); + buffer.putShort((short)0x2324); + buffer.putShort((short)0x2526); + try { + buffer.putShort((short)0x2728); + fail("Exception expected"); + } catch (BufferOverflowException e) { + // expected + } + buffer.position(3); + try { + buffer.putShort((short)0x292A); + fail("Exception expected"); + } catch (BufferOverflowException e) { + // expected + } + assertThat(buffer.get(0), is((byte)0x23)); + assertThat(buffer.get(1), is((byte)0x24)); + assertThat(buffer.get(2), is((byte)0x25)); + assertThat(buffer.get(3), is((byte)0x26)); + buffer.putShort(0, (short)0x2B2C); + assertThat(buffer.get(1), is((byte)0x2C)); + try { + buffer.putShort(3, (short)0x2D2E); + fail("Exception expected"); + } catch (IndexOutOfBoundsException e) { + // expected + } + } }