diff options
author | Matthew Khouzam | 2013-11-27 14:24:05 +0000 |
---|---|---|
committer | Matthew Khouzam | 2013-11-29 22:50:28 +0000 |
commit | 05d5bf173896a3c811b176d2041367ec5b3e7c40 (patch) | |
tree | c3948c545888e8affcf896feeea61b462d05aee0 | |
parent | e885d4489a7ed7e2cc4166fa8012ae97423abd7e (diff) | |
download | org.eclipse.linuxtools-05d5bf173896a3c811b176d2041367ec5b3e7c40.tar.gz org.eclipse.linuxtools-05d5bf173896a3c811b176d2041367ec5b3e7c40.tar.xz org.eclipse.linuxtools-05d5bf173896a3c811b176d2041367ec5b3e7c40.zip |
ctf: BitBuffer.java api overhaul
* Now 3 getters are public: get(length, extendSign), getInt(), and getLong().
Change-Id: I6848b2bde4e37580c1327f03cd025ea2bae4e134
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/18908
Tested-by: Hudson CI
IP-Clean: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Tested-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-by: Etienne Bergeron <etienne.bergeron@gmail.com>
5 files changed, 361 insertions, 41 deletions
diff --git a/lttng/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java b/lttng/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java index 3350db8580..49b551bb08 100644 --- a/lttng/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java +++ b/lttng/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java @@ -7,6 +7,7 @@ * * Contributors: * Alexandre Montplaisir - Initial API and implementation + * Matthew Khouzam - additional tests *******************************************************************************/ package org.eclipse.linuxtools.ctf.core.tests.io; @@ -25,7 +26,7 @@ import org.junit.Test; * Part of the BitBuffer tests which test the methods to read/write integers. * These are separated from the main file because the fixture is different. * - * @author alexmont + * @author Alexandre Montplaisir */ public class BitBufferIntTest { @@ -91,7 +92,7 @@ public class BitBufferIntTest { int length = 1; boolean signed = true; - int result = fixture.getInt(length, signed); + long result = fixture.get(length, signed); assertEquals(0, result); } @@ -107,12 +108,12 @@ public class BitBufferIntTest { int length = 0; boolean signed = true; - int result = fixture.getInt(length, signed); + long result = fixture.get(length, signed); assertEquals(0, result); } /** - * Run the int getInt(int,int,boolean) method test. + * Run the get method test. * * @throws CTFReaderException * Not expected @@ -123,12 +124,12 @@ public class BitBufferIntTest { int length = 0; boolean signed = true; - int result = fixture.getInt(length, signed); + long result = fixture.get(length, signed); assertEquals(0, result); } /** - * Run the int getInt(int,int,boolean) method test. + * Run the get method test. * * @throws CTFReaderException * Not expected @@ -139,13 +140,12 @@ public class BitBufferIntTest { int length = 1; boolean signed = true; - int result = fixture.getInt(length, signed); + long result = fixture.get(length, signed); assertEquals(0, result); } /** - * Run the int getInt(int,int,boolean) method test with a little-endian - * BitBuffer. + * Run the get method test with a little-endian BitBuffer. * * @throws CTFReaderException * Not expected @@ -157,15 +157,14 @@ public class BitBufferIntTest { createBuffer(le_fixture); le_fixture.position(1); int length = 24; - int result = le_fixture.getInt(length, false); + long result = le_fixture.get(length, false); /* 0x020100 downshifted */ assertEquals(0x810080, result); } /** - * Run the int getInt(int,int,boolean) method test with a little-endian - * BitBuffer. + * Run the get method test with a little-endian BitBuffer. * * @throws CTFReaderException * Not expected @@ -177,7 +176,7 @@ public class BitBufferIntTest { createBuffer(le_fixture); le_fixture.position(0); int length = 24; - int result = le_fixture.getInt(length, false); + long result = le_fixture.get(length, false); assertEquals(0x020100, result); } @@ -195,13 +194,11 @@ public class BitBufferIntTest { small_fixture.position(10); int length = 32; boolean signed = true; - - int result = small_fixture.getInt(length, signed); - assertEquals(0, result); + small_fixture.get(length, signed); } /** - * Run the int getInt(int,int,boolean) method test and expect an overflow. + * Run the get method test and expect an overflow. * * @throws CTFReaderException * Expected @@ -215,8 +212,268 @@ public class BitBufferIntTest { int length = 64; boolean signed = true; - int result = small_fixture.getInt(length, signed); - assertEquals(0, result); + small_fixture.get(length, signed); + } + + /** + * Run the getLong method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong_pos0() throws CTFReaderException { + fixture.position(0); + long result = fixture.getLong(); + assertEquals(0x01020304050607L, result); + } + + /** + * Run the getLong method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong_pos7() throws CTFReaderException { + fixture.position(7); + long result = fixture.getLong(); + assertEquals(0x81018202830384L, result); + } + + /** + * Run the getLong method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong_pos8() throws CTFReaderException { + fixture.position(8); + long result = fixture.getLong(); + assertEquals(result, 0x0102030405060708L); + } + + /** + * Run the getLong method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong_pos0LE() throws CTFReaderException { + fixture.position(0); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.getLong(); + assertEquals(result, 0x0706050403020100L); + } + + /** + * Run the getLong method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong_pos7LE() throws CTFReaderException { + fixture.position(7); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.getLong(); + assertEquals(result, 0x100e0c0a08060402L); + } + + /** + * Run the getLong method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong_pos8LE() throws CTFReaderException { + fixture.position(8); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.getLong(); + assertEquals(result, 0x0807060504030201L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGet35_pos0BE() throws CTFReaderException { + fixture.position(0); + long result = fixture.get(35, false); + assertEquals(result, 0x081018L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGet35_pos8BE() throws CTFReaderException { + fixture.position(8); + long result = fixture.get(35, false); + assertEquals(result, 0x08101820L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGet35_pos0LE() throws CTFReaderException { + fixture.position(0); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(35, false); + + assertEquals(result, 0x0403020100L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong35_pos7LE() throws CTFReaderException { + fixture.position(7); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(35, false); + assertEquals(result, 0x0208060402L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong35_pos8LE() throws CTFReaderException { + fixture.position(8); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(35, false); + assertEquals(result, 0x0504030201L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong35s_pos0LE() throws CTFReaderException { + fixture.position(0); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(35, true); + assertEquals(result, 0xfffffffc03020100L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong35s_pos7LE() throws CTFReaderException { + fixture.position(7); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(35, true); + assertEquals(result, 0x0208060402L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetLong35s_pos8LE() throws CTFReaderException { + fixture.position(8); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(35, true); + assertEquals(result, 0xfffffffd04030201L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetSigned() throws CTFReaderException { + fixture.position(0); + fixture.putInt(-1); + fixture.putInt(-1); + fixture.position(0); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(32, true); + assertEquals(result, -1L); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGetUnsigned() throws CTFReaderException { + fixture.position(0); + fixture.putInt(-1); + fixture.putInt(-1); + fixture.position(0); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(32, false); + assertEquals(0xFFFFFFFFL, result); + } + + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGet24Signed() throws CTFReaderException { + fixture.position(0); + fixture.putInt(-1); + fixture.putInt(-1); + fixture.position(0); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(24, true); + assertEquals(-1L, result); + } + + /** + * Run the get method test. + * + * @throws CTFReaderException + * error + */ + @Test + public void testGet24Unsigned() throws CTFReaderException { + fixture.position(0); + fixture.putInt(-1); + fixture.putInt(-1); + fixture.position(0); + fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); + long result = fixture.get(24, false); + assertEquals(0xFFFFFFL, result); } /** @@ -317,8 +574,6 @@ public class BitBufferIntTest { int value = 1; fixture2.putInt(length, value); - - int read = fixture2.getInt(1, true); - assertEquals(value, read); + fixture2.get(1, true); } } diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/io/BitBuffer.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/io/BitBuffer.java index 8be8954427..bb43c10f5b 100644 --- a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/io/BitBuffer.java +++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/io/BitBuffer.java @@ -6,10 +6,11 @@ * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: Matthew Khouzam - Initial Design and implementation - * Contributors: Francis Giraldeau - Initial API and implementation - * Contributors: Philippe Proulx - Some refinement and optimization - * Contributors: Etienne Bergeron <Etienne.Bergeron@gmail.com> - fix zero size read + cleanup + * Contributors: + * Matthew Khouzam - Initial Design and implementation + overhaul + * Francis Giraldeau - Initial API and implementation + * Philippe Proulx - Some refinement and optimization + * Etienne Bergeron <Etienne.Bergeron@gmail.com> - fix zero size read + cleanup *******************************************************************************/ package org.eclipse.linuxtools.ctf.core.event.io; @@ -23,6 +24,7 @@ import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; * <b><u>BitBuffer</u></b> * <p> * A bitwise buffer capable of accessing fields with bit offsets. + * * @since 2.0 */ public final class BitBuffer { @@ -95,16 +97,73 @@ public final class BitBuffer { * Reads next four bytes from the current bit position according to current * byte order. * - * @return The int value read from the buffer + * @return The int value (signed) read from the buffer * @throws CTFReaderException - * An error occurred reading the data. When the buffer is read - * beyond its end, this exception will be raised. + * An error occurred reading the long. This exception can be + * raised if the buffer tries to read out of bounds */ public int getInt() throws CTFReaderException { return getInt(BIT_INT, true); } /** + * Relative <i>get</i> method for reading 64-bit integer. + * + * Reads next eight bytes from the current bit position according to current + * byte order. + * + * @return The long value (signed) read from the buffer + * @throws CTFReaderException + * An error occurred reading the long. This exception can be + * raised if the buffer tries to read out of bounds + */ + public long getLong() throws CTFReaderException { + return get(BIT_LONG, true); + } + + /** + * Relative <i>get</i> method for reading long of <i>length</i> bits. + * + * Reads <i>length</i> bits starting at the current position. The result is + * signed extended if <i>signed</i> is true. The current position is + * increased of <i>length</i> bits. + * + * @param length + * The length in bits of this integer + * @param signed + * The sign extended flag + * @return The long value read from the buffer + * @throws CTFReaderException + * An error occurred reading the data. If more than 64 bits at a + * time are read, or the buffer is read beyond its end, this + * exception will be raised. + */ + public long get(int length, boolean signed) throws CTFReaderException { + if (length > BIT_LONG) { + throw new CTFReaderException("Cannot read a long longer than 64 bits. Rquested: " + length); //$NON-NLS-1$ + } + if (length > BIT_INT) { + final int highShift = length - BIT_INT; + long a = getInt(); + long b = getInt(highShift, false); + long retVal; + /* Cast the signed-extended int into a unsigned int. */ + a &= 0xFFFFFFFFL; + b &= (1L << highShift) - 1L; + + retVal = (this.byteOrder == ByteOrder.BIG_ENDIAN) ? ((a << highShift) | b) : ((b << BIT_INT) | a); + /* sign extend */ + if (signed) { + int signExtendBits = BIT_LONG - length; + retVal = (retVal << signExtendBits) >> signExtendBits; + } + return retVal; + } + long retVal = getInt(length, signed); + return (signed ? retVal : (retVal & 0xFFFFFFFFL)); + } + + /** * Relative <i>get</i> method for reading integer of <i>length</i> bits. * * Reads <i>length</i> bits starting at the current position. The result is @@ -120,7 +179,7 @@ public final class BitBuffer { * An error occurred reading the data. When the buffer is read * beyond its end, this exception will be raised. */ - public int getInt(int length, boolean signed) throws CTFReaderException { + private int getInt(int length, boolean signed) throws CTFReaderException { /* Nothing to read. */ if (length == 0) { @@ -138,9 +197,15 @@ public final class BitBuffer { int val = 0; boolean gotIt = false; - /* Try a fast read when the position is byte-aligned by using the */ - /* native methods of ByteBuffer. */ - if (this.pos % BitBuffer.BIT_CHAR == 0) { + /* + * Try a fast read when the position is byte-aligned by using + * java.nio.ByteBuffer's native methods + */ + /* + * A faster alignment detection as the compiler cannot guaranty that pos + * is always positive. + */ + if ((this.pos & (BitBuffer.BIT_CHAR - 1)) == 0) { switch (length) { case BitBuffer.BIT_CHAR: // Byte diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/FloatDefinition.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/FloatDefinition.java index 16b7509e48..9543df4103 100644 --- a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/FloatDefinition.java +++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/FloatDefinition.java @@ -103,9 +103,9 @@ public class FloatDefinition extends Definition { private static double readRawFloat64(BitBuffer input, final int manBits, final int expBits) throws CTFReaderException { - long low = input.getInt(32, false); + long low = input.get(32, false); low = low & 0x00000000FFFFFFFFL; - long high = input.getInt(32, false); + long high = input.get(32, false); high = high & 0x00000000FFFFFFFFL; long temp = (high << 32) | low; return createFloat(temp, manBits - 1, expBits); @@ -135,7 +135,7 @@ public class FloatDefinition extends Definition { private static double readRawFloat32(BitBuffer input, final int manBits, final int expBits) throws CTFReaderException { - long temp = input.getInt(32, false); + long temp = input.get(32, false); return createFloat(temp, manBits - 1, expBits); } diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/IntegerDefinition.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/IntegerDefinition.java index 1cb980c02b..31a9cd501b 100644 --- a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/IntegerDefinition.java +++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/IntegerDefinition.java @@ -122,9 +122,9 @@ public class IntegerDefinition extends SimpleDatatypeDefinition { // TODO: use the eventual getLong from BitBuffer if (length == 64) { - long low = input.getInt(32, false); + long low = input.get(32, false); low = low & 0x00000000FFFFFFFFL; - long high = input.getInt(32, false); + long high = input.get(32, false); high = high & 0x00000000FFFFFFFFL; if (this.declaration.getByteOrder() != ByteOrder.BIG_ENDIAN) { bits = (high << 32) | low; @@ -132,7 +132,7 @@ public class IntegerDefinition extends SimpleDatatypeDefinition { bits = (low << 32) | high; } } else { - bits = input.getInt(length, signed); + bits = input.get(length, signed); bits = bits & 0x00000000FFFFFFFFL; /* * The previous line loses sign information but is necessary, this diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/StringDefinition.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/StringDefinition.java index 5e79cef7bf..6ed3c0c87d 100644 --- a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/StringDefinition.java +++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/event/types/StringDefinition.java @@ -115,10 +115,10 @@ public class StringDefinition extends Definition { /* Offset the buffer position wrt the current alignment */ alignRead(input, this.declaration); string.setLength(0); - char c = (char) input.getInt(8, false); + char c = (char) input.get(8, false); while (c != 0) { string.append(c); - c = (char) input.getInt(8, false); + c = (char) input.get(8, false); } } |