From 814c8f80d51dd3b128fba906bfcb746a697c555f Mon Sep 17 00:00:00 2001 From: Mike Poindexter Date: Mon, 20 Jul 2015 18:09:50 -0700 Subject: [PATCH] Various fixes to ByteBuffer -Fix exception when put()'ing a zero byte array -Fix getInt() methods returning a short value -Fix relative get() using the index instead of the supplied position -Add long put/get --- .../teavm/classlib/java/nio/TByteBuffer.java | 11 ++ .../classlib/java/nio/TByteBufferImpl.java | 118 ++++++++++++++++-- 2 files changed, 121 insertions(+), 8 deletions(-) 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 ddadfb53a..a7338fef4 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 @@ -86,6 +86,9 @@ public abstract class TByteBuffer extends TBuffer implements TComparable= 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; + int a = array[start + index] & 0xFF; + int b = array[start + index + 1] & 0xFF; + int c = array[start + index + 2] & 0xFF; + int d = array[start + index + 3] & 0xFF; if (order == TByteOrder.BIG_ENDIAN) { - return (short)((a << 24) | (b << 16) | (c << 8) | d); + return (int)((a << 24) | (b << 16) | (c << 8) | d); } else { - return (short)((d << 24) | (c << 16) | (b << 8) | a); + return (int)((d << 24) | (c << 16) | (b << 8) | a); } } @@ -340,6 +340,108 @@ class TByteBufferImpl extends TByteBuffer { } } + @Override + public long getLong() { + if (position + 7 >= limit) { + throw new TBufferUnderflowException(); + } + long a = array[start + position] & 0xFF; + long b = array[start + position + 1] & 0xFF; + long c = array[start + position + 2] & 0xFF; + long d = array[start + position + 3] & 0xFF; + long e = array[start + position + 4] & 0xFF; + long f = array[start + position + 5] & 0xFF; + long g = array[start + position + 6] & 0xFF; + long h = array[start + position + 7] & 0xFF; + position += 8; + if (order == TByteOrder.BIG_ENDIAN) { + return (long)((a << 56) | (b << 48) | (c << 40) | (d << 32) | (e << 24) | (f << 16) | (g << 8) | h); + } else { + return (long)((h << 56) | (g << 48) | (f << 40) | (e << 32) | (d << 24) | (c << 16) | (b << 8) | a); + } + } + + @Override + public TByteBuffer putLong(long value) { + if (readOnly) { + throw new TReadOnlyBufferException(); + } + if (position + 7 >= limit) { + throw new TBufferOverflowException(); + } + if (order == TByteOrder.BIG_ENDIAN) { + array[start + position++] = (byte)(value >> 56); + array[start + position++] = (byte)(value >> 48); + array[start + position++] = (byte)(value >> 40); + array[start + position++] = (byte)(value >> 32); + 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); + array[start + position++] = (byte)(value >> 32); + array[start + position++] = (byte)(value >> 40); + array[start + position++] = (byte)(value >> 48); + array[start + position++] = (byte)(value >> 56); + } + return this; + } + + @Override + public long getLong(int index) { + if (index < 0 || index + 7 >= limit) { + throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + (limit - 7) + ")"); + } + long a = array[start + index] & 0xFF; + long b = array[start + index + 1] & 0xFF; + long c = array[start + index + 2] & 0xFF; + long d = array[start + index + 3] & 0xFF; + long e = array[start + index + 4] & 0xFF; + long f = array[start + index + 5] & 0xFF; + long g = array[start + index + 6] & 0xFF; + long h = array[start + index + 7] & 0xFF; + position += 8; + if (order == TByteOrder.BIG_ENDIAN) { + return (long)((a << 56) | (b << 48) | (c << 40) | (d << 32) | (e << 24) | (f << 16) | (g << 8) | h); + } else { + return (long)((h << 56) | (g << 48) | (f << 40) | (e << 32) | (d << 24) | (c << 16) | (b << 8) | a); + } + } + + @Override + public TByteBuffer putLong(int index, long 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 + 0] = (byte)(value >> 56); + array[start + index + 1] = (byte)(value >> 48); + array[start + index + 2] = (byte)(value >> 40); + array[start + index + 3] = (byte)(value >> 32); + array[start + index + 4] = (byte)(value >> 24); + array[start + index + 5] = (byte)(value >> 16); + array[start + index + 6] = (byte)(value >> 8); + array[start + index + 7] = (byte)value; + } else { + array[start + index + 0] = (byte)value; + array[start + index + 1] = (byte)(value >> 8); + array[start + index + 2] = (byte)(value >> 16); + array[start + index + 3] = (byte)(value >> 24); + array[start + index + 4] = (byte)(value >> 24); + array[start + index + 5] = (byte)(value >> 24); + array[start + index + 6] = (byte)(value >> 24); + array[start + index + 7] = (byte)(value >> 24); + } + return this; + } + @Override public TLongBuffer asLongBuffer() { int sz = remaining() / 8;