Support the little endian floats and doubles by ByteBuf
Motivation: `ByteBuf` does not have the little endian variant of float/double access methods. Modifications: Add support for little endian floats and doubles into `ByteBuf`. Result: `ByteBuf` has get/read/set/writeFloatLE() and get/read/set/writeDoubleLE() methods. Fixes [#6576].
This commit is contained in:
parent
4875a2aad4
commit
0774c91456
@ -757,6 +757,20 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract float getFloat(int index);
|
||||
|
||||
/**
|
||||
* Gets a 32-bit floating point number at the specified absolute
|
||||
* {@code index} in this buffer in Little Endian Byte Order.
|
||||
* This method does not modify {@code readerIndex} or
|
||||
* {@code writerIndex} of this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if the specified {@code index} is less than {@code 0} or
|
||||
* {@code index + 4} is greater than {@code this.capacity}
|
||||
*/
|
||||
public float getFloatLE(int index) {
|
||||
return Float.intBitsToFloat(getIntLE(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a 64-bit floating point number at the specified absolute
|
||||
* {@code index} in this buffer. This method does not modify
|
||||
@ -768,6 +782,20 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract double getDouble(int index);
|
||||
|
||||
/**
|
||||
* Gets a 64-bit floating point number at the specified absolute
|
||||
* {@code index} in this buffer in Little Endian Byte Order.
|
||||
* This method does not modify {@code readerIndex} or
|
||||
* {@code writerIndex} of this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if the specified {@code index} is less than {@code 0} or
|
||||
* {@code index + 8} is greater than {@code this.capacity}
|
||||
*/
|
||||
public double getDoubleLE(int index) {
|
||||
return Double.longBitsToDouble(getLongLE(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers this buffer's data to the specified destination starting at
|
||||
* the specified absolute {@code index} until the destination becomes
|
||||
@ -1089,6 +1117,20 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract ByteBuf setFloat(int index, float value);
|
||||
|
||||
/**
|
||||
* Sets the specified 32-bit floating-point number at the specified
|
||||
* absolute {@code index} in this buffer in Little Endian Byte Order.
|
||||
* This method does not modify {@code readerIndex} or {@code writerIndex} of
|
||||
* this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if the specified {@code index} is less than {@code 0} or
|
||||
* {@code index + 4} is greater than {@code this.capacity}
|
||||
*/
|
||||
public ByteBuf setFloatLE(int index, float value) {
|
||||
return setIntLE(index, Float.floatToRawIntBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified 64-bit floating-point number at the specified
|
||||
* absolute {@code index} in this buffer.
|
||||
@ -1101,6 +1143,20 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract ByteBuf setDouble(int index, double value);
|
||||
|
||||
/**
|
||||
* Sets the specified 64-bit floating-point number at the specified
|
||||
* absolute {@code index} in this buffer in Little Endian Byte Order.
|
||||
* This method does not modify {@code readerIndex} or {@code writerIndex} of
|
||||
* this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if the specified {@code index} is less than {@code 0} or
|
||||
* {@code index + 8} is greater than {@code this.capacity}
|
||||
*/
|
||||
public ByteBuf setDoubleLE(int index, double value) {
|
||||
return setLongLE(index, Double.doubleToRawLongBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the specified source buffer's data to this buffer starting at
|
||||
* the specified absolute {@code index} until the source buffer becomes
|
||||
@ -1463,6 +1519,18 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract float readFloat();
|
||||
|
||||
/**
|
||||
* Gets a 32-bit floating point number at the current {@code readerIndex}
|
||||
* in Little Endian Byte Order and increases the {@code readerIndex}
|
||||
* by {@code 4} in this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code this.readableBytes} is less than {@code 4}
|
||||
*/
|
||||
public float readFloatLE() {
|
||||
return Float.intBitsToFloat(readIntLE());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a 64-bit floating point number at the current {@code readerIndex}
|
||||
* and increases the {@code readerIndex} by {@code 8} in this buffer.
|
||||
@ -1472,6 +1540,18 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract double readDouble();
|
||||
|
||||
/**
|
||||
* Gets a 64-bit floating point number at the current {@code readerIndex}
|
||||
* in Little Endian Byte Order and increases the {@code readerIndex}
|
||||
* by {@code 8} in this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code this.readableBytes} is less than {@code 8}
|
||||
*/
|
||||
public double readDoubleLE() {
|
||||
return Double.longBitsToDouble(readLongLE());
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers this buffer's data to a newly created buffer starting at
|
||||
* the current {@code readerIndex} and increases the {@code readerIndex}
|
||||
@ -1794,6 +1874,18 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract ByteBuf writeFloat(float value);
|
||||
|
||||
/**
|
||||
* Sets the specified 32-bit floating point number at the current
|
||||
* {@code writerIndex} in Little Endian Byte Order and increases
|
||||
* the {@code writerIndex} by {@code 4} in this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code this.writableBytes} is less than {@code 4}
|
||||
*/
|
||||
public ByteBuf writeFloatLE(float value) {
|
||||
return writeIntLE(Float.floatToRawIntBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified 64-bit floating point number at the current
|
||||
* {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
|
||||
@ -1804,6 +1896,18 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract ByteBuf writeDouble(double value);
|
||||
|
||||
/**
|
||||
* Sets the specified 64-bit floating point number at the current
|
||||
* {@code writerIndex} in Little Endian Byte Order and increases
|
||||
* the {@code writerIndex} by {@code 8} in this buffer.
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code this.writableBytes} is less than {@code 8}
|
||||
*/
|
||||
public ByteBuf writeDoubleLE(double value) {
|
||||
return writeLongLE(Double.doubleToRawLongBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the specified source buffer's data to this buffer starting at
|
||||
* the current {@code writerIndex} until the source buffer becomes
|
||||
|
@ -786,29 +786,57 @@ public abstract class AbstractByteBufTest {
|
||||
|
||||
@Test
|
||||
public void testRandomFloatAccess() {
|
||||
testRandomFloatAccess(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomFloatLEAccess() {
|
||||
testRandomFloatAccess(false);
|
||||
}
|
||||
|
||||
private void testRandomFloatAccess(boolean testBigEndian) {
|
||||
for (int i = 0; i < buffer.capacity() - 7; i += 8) {
|
||||
float value = random.nextFloat();
|
||||
buffer.setFloat(i, value);
|
||||
if (testBigEndian) {
|
||||
buffer.setFloat(i, value);
|
||||
} else {
|
||||
buffer.setFloatLE(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
random.setSeed(seed);
|
||||
for (int i = 0; i < buffer.capacity() - 7; i += 8) {
|
||||
float value = random.nextFloat();
|
||||
assertEquals(value, buffer.getFloat(i), 0.01);
|
||||
float expected = random.nextFloat();
|
||||
float actual = testBigEndian? buffer.getFloat(i) : buffer.getFloatLE(i);
|
||||
assertEquals(expected, actual, 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomDoubleAccess() {
|
||||
testRandomDoubleAccess(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomDoubleLEAccess() {
|
||||
testRandomDoubleAccess(false);
|
||||
}
|
||||
|
||||
private void testRandomDoubleAccess(boolean testBigEndian) {
|
||||
for (int i = 0; i < buffer.capacity() - 7; i += 8) {
|
||||
double value = random.nextDouble();
|
||||
buffer.setDouble(i, value);
|
||||
if (testBigEndian) {
|
||||
buffer.setDouble(i, value);
|
||||
} else {
|
||||
buffer.setDoubleLE(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
random.setSeed(seed);
|
||||
for (int i = 0; i < buffer.capacity() - 7; i += 8) {
|
||||
double value = random.nextDouble();
|
||||
assertEquals(value, buffer.getDouble(i), 0.01);
|
||||
double expected = random.nextDouble();
|
||||
double actual = testBigEndian? buffer.getDouble(i) : buffer.getDoubleLE(i);
|
||||
assertEquals(expected, actual, 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2615,11 +2643,21 @@ public abstract class AbstractByteBufTest {
|
||||
releasedBuffer().getFloat(0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testGetFloatLEAfterRelease() {
|
||||
releasedBuffer().getFloatLE(0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testGetDoubleAfterRelease() {
|
||||
releasedBuffer().getDouble(0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testGetDoubleLEAfterRelease() {
|
||||
releasedBuffer().getDoubleLE(0);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testGetBytesAfterRelease() {
|
||||
ByteBuf buffer = buffer(8);
|
||||
@ -2919,11 +2957,21 @@ public abstract class AbstractByteBufTest {
|
||||
releasedBuffer().readFloat();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testReadFloatLEAfterRelease() {
|
||||
releasedBuffer().readFloatLE();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testReadDoubleAfterRelease() {
|
||||
releasedBuffer().readDouble();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testReadDoubleLEAfterRelease() {
|
||||
releasedBuffer().readDoubleLE();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testReadBytesAfterRelease() {
|
||||
releasedBuffer().readBytes(1);
|
||||
@ -3049,11 +3097,21 @@ public abstract class AbstractByteBufTest {
|
||||
releasedBuffer().writeFloat(1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testWriteFloatLEAfterRelease() {
|
||||
releasedBuffer().writeFloatLE(1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testWriteDoubleAfterRelease() {
|
||||
releasedBuffer().writeDouble(1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testWriteDoubleLEAfterRelease() {
|
||||
releasedBuffer().writeDoubleLE(1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalReferenceCountException.class)
|
||||
public void testWriteBytesAfterRelease() {
|
||||
ByteBuf buffer = buffer(8);
|
||||
|
Loading…
Reference in New Issue
Block a user