Merge pull request #142 from mpoindexter/master-fix-bytebuffer

Various fixes to ByteBuffer
This commit is contained in:
Alexey Andreev 2015-07-21 18:37:26 +03:00
commit 3cc63c1071
3 changed files with 227 additions and 8 deletions

View File

@ -86,6 +86,9 @@ public abstract class TByteBuffer extends TBuffer implements TComparable<TByteBu
}
public TByteBuffer put(byte[] src, int offset, int length) {
if (length == 0) {
return this;
}
if (isReadOnly()) {
throw new TReadOnlyBufferException();
}
@ -229,6 +232,14 @@ public abstract class TByteBuffer extends TBuffer implements TComparable<TByteBu
public abstract TIntBuffer asIntBuffer();
public abstract long getLong();
public abstract TByteBuffer putLong(long value);
public abstract long getLong(int index);
public abstract TByteBuffer putLong(int index, long value);
public abstract TLongBuffer asLongBuffer();
public abstract TFloatBuffer asFloatBuffer();

View File

@ -264,9 +264,9 @@ class TByteBufferImpl extends TByteBuffer {
int d = array[start + position + 3] & 0xFF;
position += 4;
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);
}
}
@ -297,14 +297,14 @@ class TByteBufferImpl extends TByteBuffer {
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;
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;

View File

@ -345,6 +345,17 @@ public class ByteBufferTest {
assertThat(array, is(new byte[] {0, 2, 3, 0 }));
}
@Test
public void putsBytesWithZeroLengthArray() {
byte[] array = new byte[4];
ByteBuffer buffer = ByteBuffer.wrap(array);
buffer.get();
byte[] data = { };
buffer.put(data, 0, 0);
assertThat(buffer.position(), is(1));
assertThat(array, is(new byte[] {0, 0, 0, 0 }));
}
@Test
public void compacts() {
byte[] array = { 2, 3, 5, 7 };
@ -498,4 +509,99 @@ public class ByteBufferTest {
// expected
}
}
@Test
public void getsInt() {
byte[] array = { 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30 };
ByteBuffer buffer = ByteBuffer.wrap(array);
assertThat(buffer.getInt(), is(0x23242526));
assertThat(buffer.getInt(), is(0x27282930));
try {
buffer.getInt();
fail("Exception expected");
} catch (BufferUnderflowException e) {
// expected
}
buffer.position(7);
try {
buffer.getInt();
fail("Exception expected");
} catch (BufferUnderflowException e) {
// expected
}
assertThat(buffer.getInt(0), is(0x23242526));
assertThat(buffer.getInt(4), is(0x27282930));
try {
buffer.getInt(7);
fail("Exception expected");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
@Test
public void getsLong() {
byte[] array = { 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 };
ByteBuffer buffer = ByteBuffer.wrap(array);
assertThat(buffer.getLong(), is(0x2324252627282930L));
assertThat(buffer.getLong(), is(0x3132333435363738L));
try {
buffer.getLong();
fail("Exception expected");
} catch (BufferUnderflowException e) {
// expected
}
buffer.position(15);
try {
buffer.getLong();
fail("Exception expected");
} catch (BufferUnderflowException e) {
// expected
}
assertThat(buffer.getLong(0), is(0x2324252627282930L));
assertThat(buffer.getLong(8), is(0x3132333435363738L));
try {
buffer.getLong(16);
fail("Exception expected");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
@Test
public void putsLong() {
byte[] array = new byte[16];
ByteBuffer buffer = ByteBuffer.wrap(array);
buffer.putLong(0x2324252627282930L);
buffer.putLong(0x3132333435363738L);
try {
buffer.putLong(0L);
fail("Exception expected");
} catch (BufferOverflowException e) {
// expected
}
buffer.position(15);
try {
buffer.putLong(0L);
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));
assertThat(buffer.get(4), is((byte)0x27));
assertThat(buffer.get(5), is((byte)0x28));
assertThat(buffer.get(6), is((byte)0x29));
assertThat(buffer.get(7), is((byte)0x30));
buffer.putLong(0, 0xAABBCCDDEEFF0000L);
assertThat(buffer.get(1), is((byte)0xBB));
try {
buffer.putLong(15, 0x0L);
fail("Exception expected");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
}