From 8b8e48edb3d6614c959470679c0eb3a3126dfa07 Mon Sep 17 00:00:00 2001 From: Matthew Khouzam Date: Thu, 2 Aug 2012 13:27:03 -0400 Subject: [PATCH 1/1] ctf: BitBuffer improvements Minor performance improvements. Simplified the API a bit: Removed the 'index' parameter from the public API in read() and put() methods. All reads/writes can be done from the current position, and this position can be set with position(). Updated the tests accordingly. Change-Id: I24b30f2a2e5d79be1b873795ebd4183b70551907 Signed-off-by: Matthew Khouzam Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/7076 Reviewed-by: Philippe Proulx --- .../ctf/core/tests/io/BitBufferIntTest.java | 46 +- .../ctf/core/tests/io/BitBufferTest.java | 20 +- .../internal/ctf/core/event/io/BitBuffer.java | 1037 ++++++++--------- .../internal/ctf/core/trace/StreamInput.java | 4 +- 4 files changed, 528 insertions(+), 579 deletions(-) diff --git a/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java b/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java index 79b4bc2fc7..22fee78a6b 100644 --- a/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java +++ b/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferIntTest.java @@ -13,9 +13,9 @@ import org.junit.Test; /** * Part of the BitBuffet tests with test the methods to read/write integers. * These are separated from the main file because the fixture is different. - * + * * @author alexmont - * + * */ public class BitBufferIntTest { @@ -23,7 +23,7 @@ public class BitBufferIntTest { /** * Launch the test. - * + * * @param args * the command line arguments */ @@ -113,11 +113,10 @@ public class BitBufferIntTest { @Test public void testGetInt_signed() { fixture.position(1); - int index = 1; int length = 0; boolean signed = true; - int result = fixture.getInt(index, length, signed); + int result = fixture.getInt(length, signed); assertEquals(0, result); } @@ -127,11 +126,10 @@ public class BitBufferIntTest { @Test public void testGetInt_signed_length1() { fixture.position(1); - int index = 1; int length = 1; boolean signed = true; - int result = fixture.getInt(index, length, signed); + int result = fixture.getInt(length, signed); assertEquals(0, result); } @@ -146,9 +144,8 @@ public class BitBufferIntTest { le_fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); createBuffer(le_fixture); le_fixture.position(1); - int index = 1; int length = 24; - int result = le_fixture.getInt(index, length, false); + int result = le_fixture.getInt(length, false); /* 0x020100 downshifted */ assertEquals(0x810080, result); @@ -165,9 +162,8 @@ public class BitBufferIntTest { le_fixture.setByteOrder(ByteOrder.LITTLE_ENDIAN); createBuffer(le_fixture); le_fixture.position(0); - int index = 0; int length = 24; - int result = le_fixture.getInt(index, length, false); + int result = le_fixture.getInt(length, false); assertEquals(0x020100, result); } @@ -198,11 +194,10 @@ public class BitBufferIntTest { small_fixture.setByteOrder(ByteOrder.BIG_ENDIAN); createBuffer(small_fixture, 2); small_fixture.position(1); - int index = 1; int length = 64; boolean signed = true; - int result = small_fixture.getInt(index, length, signed); + int result = small_fixture.getInt(length, signed); assertEquals(0, result); } @@ -233,12 +228,11 @@ public class BitBufferIntTest { */ @Test public void testPutInt_length0() { - int index = 1; int length = 0; int value = 1; fixture.position(1); - fixture.putInt(index, length, value); + fixture.putInt(length, value); } /** @@ -246,12 +240,11 @@ public class BitBufferIntTest { */ @Test public void testPutInt_length1() { - int index = 1; int length = 1; int value = 1; fixture.position(1); - fixture.putInt(index, length, value); + fixture.putInt(length, value); } /** @@ -259,12 +252,18 @@ public class BitBufferIntTest { */ @Test public void testPutInt_hex() { - int value = 0x010203; + final int value = 0x010203; + int read; - fixture.position(1); - fixture.putInt(value); - int read = fixture.getInt(); - assertEquals(value, read); + for (int i = 0; i <= 32; i++) { + fixture.position(i); + fixture.putInt(value); + + fixture.position(i); + read = fixture.getInt(); + + assertEquals(value, read); + } } /** @@ -278,11 +277,10 @@ public class BitBufferIntTest { createBuffer(fixture2, 4); fixture2.position(1); - int index = 16; int length = 32; int value = 1; - fixture2.putInt(index, length, value); + fixture2.putInt(length, value); int read = fixture2.getInt(1, true); assertEquals(value, read); diff --git a/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferTest.java b/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferTest.java index a8edb89e7b..18e6fcecc6 100644 --- a/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferTest.java +++ b/org.eclipse.linuxtools.ctf.core.tests/src/org/eclipse/linuxtools/ctf/core/tests/io/BitBufferTest.java @@ -14,7 +14,7 @@ import org.junit.Test; /** * The class BitBufferTest contains tests for the class * {@link BitBuffer}. - * + * * @author ematkho * @version $Revision: 1.0 $ */ @@ -24,7 +24,7 @@ public class BitBufferTest { /** * Launch the test. - * + * * @param args * the command line arguments */ @@ -86,18 +86,6 @@ public class BitBufferTest { assertEquals(false, result); } - /** - * Run the boolean canRead(int,int) method test. - */ - @Test - public void testCanRead_2params() { - int index = 1; - int length = 1; - boolean result = fixture.canRead(index, length); - - assertEquals(false, result); - } - /** * Run the void clear() method test. */ @@ -143,7 +131,7 @@ public class BitBufferTest { */ @Test public void testGetOrder() { - ByteOrder result = fixture.order(); + ByteOrder result = fixture.getByteOrder(); assertNotNull(result); assertEquals("BIG_ENDIAN", result.toString()); //$NON-NLS-1$ @@ -156,7 +144,7 @@ public class BitBufferTest { public void testSetOrder() { ByteOrder order = ByteOrder.BIG_ENDIAN; - fixture.order(order); + fixture.setByteOrder(order); } /** diff --git a/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/event/io/BitBuffer.java b/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/event/io/BitBuffer.java index 341c93ccb9..7440b39c68 100644 --- a/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/event/io/BitBuffer.java +++ b/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/event/io/BitBuffer.java @@ -1,595 +1,558 @@ /*******************************************************************************. - * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others - * - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which - * 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 - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.ctf.core.event.io; - -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * BitBuffer - *

- * A bitwise buffer capable of accessing fields with bit offsets. - */ -public class BitBuffer { - - // ------------------------------------------------------------------------ - // Constants - // ------------------------------------------------------------------------ - - /* default bit width */ - /** 8 bits to a char */ - public static final int BIT_CHAR = 8; - /** 16 bits to a short */ - public static final int BIT_SHORT = 16; - /** 32 bits to an int */ - public static final int BIT_INT = 32; - /** 32 bits to a float */ - public static final int BIT_FLOAT = 32; - /** 64 bits to a long */ - public static final int BIT_LONG = 64; - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private ByteBuffer buf; - private int pos; - private ByteOrder byteOrder; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - /** - * Default constructor, makes a bigendian buffer - */ - public BitBuffer() { - this(null, ByteOrder.BIG_ENDIAN); - } - - /** - * Constructor, makes a bigendian buffer + * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others * - * @param buf - * the bytebuffer to read - */ - public BitBuffer(ByteBuffer buf) { - this(buf, ByteOrder.BIG_ENDIAN); - } - - /** - * Constructor that is fully parametrisable + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html * - * @param buf - * the buffer to read - * @param order - * the byte order (big endian, little endian, network?) - */ - public BitBuffer(ByteBuffer buf, ByteOrder order) { - setByteBuffer(buf); - order(order); - position(0); - } + * Contributors: Matthew Khouzam - Initial Design and implementation + * Contributors: Francis Giraldeau - Initial API and implementation + * Contributors: Philippe Proulx - Some refinement and optimization + *******************************************************************************/ - // ------------------------------------------------------------------------ - // 'Get' operations on buffer - // ------------------------------------------------------------------------ + package org.eclipse.linuxtools.internal.ctf.core.event.io; - /** - * Relative get method for reading 32-bit integer. - * - * Reads next four bytes from the current bit position according to current - * byte order. - * - * @return The int value read from the buffer - */ - public int getInt() { - int val = getInt(BIT_INT, true); - pos += BIT_INT; - return val; - } + import java.nio.BufferOverflowException; + import java.nio.ByteBuffer; + import java.nio.ByteOrder; /** - * Relative get method for reading integer of length bits. - * - * Reads length bits starting at the current position. The result is - * signed extended if signed is true. The current position is - * increased of length bits. - * - * @param length - * The length in bits of this integer - * @param signed - * The sign extended flag - * @return The int value read from the buffer + * BitBuffer + *

+ * A bitwise buffer capable of accessing fields with bit offsets. */ - public int getInt(int length, boolean signed) { - int val; - if (!canRead(pos, length)) { - throw new BufferOverflowException(); - } - if (length == 0) { - val = 0; - } - if (byteOrder == ByteOrder.LITTLE_ENDIAN) { - val = getIntLE(pos, length, signed); - } else { - val = getIntBE(pos, length, signed); + public class BitBuffer { + + // ------------------------------------------------------------------------ + // Constants + // ------------------------------------------------------------------------ + + /* default bit width */ + /** 8 bits to a char */ + public static final int BIT_CHAR = 8; + /** 16 bits to a short */ + public static final int BIT_SHORT = 16; + /** 32 bits to an int */ + public static final int BIT_INT = 32; + /** 32 bits to a float */ + public static final int BIT_FLOAT = 32; + /** 64 bits to a long */ + public static final int BIT_LONG = 64; + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private ByteBuffer buf; + private int pos; + private ByteOrder byteOrder; + + // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ + /** + * Default constructor, makes a bigendian buffer + */ + public BitBuffer() { + this(null, ByteOrder.BIG_ENDIAN); } - pos += length; - return val; - } - /** - * Absolute get method for reading integer of length bits. - * - * Reads length bits starting from position index. The result - * is signed extended if signed is true. The current position is - * increased of length bits. - * - * @param index - * The start index in bits - * @param length - * The length in bits to read - * @param signed - * The sign extended flag - * @return The int value read from the buffer - */ - public int getInt(int index, int length, boolean signed) { - if (!canRead(index, length)) { - throw new BufferOverflowException(); - } - if (length == 0) { - return 0; - } - if (byteOrder == ByteOrder.LITTLE_ENDIAN) { - return getIntLE(index, length, signed); + /** + * Constructor, makes a bigendian buffer + * + * @param buf + * the bytebuffer to read + */ + public BitBuffer(ByteBuffer buf) { + this(buf, ByteOrder.BIG_ENDIAN); } - return getIntBE(index, length, signed); - } - private int getIntBE(int index, int length, boolean signed) { - assert ((length > 0) && (length <= BIT_INT)); - int end = index + length; - int startByte = index / BIT_CHAR; - int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; - int currByte, lshift, cshift, mask, cmask, cache; - int value = 0; - - currByte = startByte; - cache = buf.get(currByte) & 0xFF; - boolean isNeg = (cache & (1 << (BIT_CHAR - (index % BIT_CHAR) - 1))) != 0; - if (signed && isNeg) { - value = ~0; + /** + * Constructor that is fully parametrisable + * + * @param buf + * the buffer to read + * @param order + * the byte order (big endian, little endian, network?) + */ + public BitBuffer(ByteBuffer buf, ByteOrder order) { + setByteBuffer(buf); + setByteOrder(order); + position(0); + } + + // ------------------------------------------------------------------------ + // 'Get' operations on buffer + // ------------------------------------------------------------------------ + + /** + * Relative get method for reading 32-bit integer. + * + * Reads next four bytes from the current bit position according to current + * byte order. + * + * @return The int value read from the buffer + */ + public int getInt() { + int val = getInt(BIT_INT, true); + return val; + } + + /** + * Relative get method for reading integer of length bits. + * + * Reads length bits starting at the current position. The result is + * signed extended if signed is true. The current position is + * increased of length bits. + * + * @param length + * The length in bits of this integer + * @param signed + * The sign extended flag + * @return The int value read from the buffer + */ + public int getInt(int length, boolean signed) { + int val = 0; + if (!canRead(length)) { + throw new BufferOverflowException(); + } + if (length == 0) { + return 0; + } + boolean gotIt = false; + + // Fall back to fast ByteBuffer reader if we want to read byte-aligned bytes + if (this.pos % BitBuffer.BIT_CHAR == 0) { + switch (length) { + case BitBuffer.BIT_CHAR: + // Byte + if (signed) { + val = this.buf.get(this.pos / 8); + } else { + val = (this.buf.get(this.pos / 8)) & 0xff; + } + gotIt = true; + break; + + case BitBuffer.BIT_SHORT: + // Word + if (signed) { + val = this.buf.getShort(this.pos / 8); + } else { + short a = this.buf.getShort(this.pos / 8); + val = a & 0xffff; + } + gotIt = true; + break; + + case BitBuffer.BIT_INT: + // Double word + val = this.buf.getInt(this.pos / 8); + gotIt = true; + break; + + default: + break; + } + } + if (!gotIt) { + // Nothing read yet: use longer methods + if (this.byteOrder == ByteOrder.LITTLE_ENDIAN) { + val = getIntLE(this.pos, length, signed); + } else { + val = getIntBE(this.pos, length, signed); + } + } + this.pos += length; + + return val; } - if (startByte == (endByte - 1)) { - cmask = cache >>> ((BIT_CHAR - (end % BIT_CHAR)) % BIT_CHAR); - if (((length) % BIT_CHAR) > 0) { - mask = ~((~0) << length); + + private int getIntBE(int index, int length, boolean signed) { + assert ((length > 0) && (length <= BIT_INT)); + int end = index + length; + int startByte = index / BIT_CHAR; + int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; + int currByte, lshift, cshift, mask, cmask, cache; + int value = 0; + + currByte = startByte; + cache = this.buf.get(currByte) & 0xFF; + boolean isNeg = (cache & (1 << (BIT_CHAR - (index % BIT_CHAR) - 1))) != 0; + if (signed && isNeg) { + value = ~0; + } + if (startByte == (endByte - 1)) { + cmask = cache >>> ((BIT_CHAR - (end % BIT_CHAR)) % BIT_CHAR); + if (((length) % BIT_CHAR) > 0) { + mask = ~((~0) << length); + cmask &= mask; + } + value <<= length; + value |= cmask; + return value; + } + cshift = index % BIT_CHAR; + if (cshift > 0) { + mask = ~((~0) << (BIT_CHAR - cshift)); + cmask = cache & mask; + lshift = BIT_CHAR - cshift; + value <<= lshift; + value |= cmask; + // index += lshift; + currByte++; + } + for (; currByte < (endByte - 1); currByte++) { + value <<= BIT_CHAR; + value |= this.buf.get(currByte) & 0xFF; + } + lshift = end % BIT_CHAR; + if (lshift > 0) { + mask = ~((~0) << lshift); + cmask = this.buf.get(currByte) & 0xFF; + cmask >>>= BIT_CHAR - lshift; cmask &= mask; + value <<= lshift; + value |= cmask; + } else { + value <<= BIT_CHAR; + value |= this.buf.get(currByte) & 0xFF; } - value <<= length; - value |= cmask; return value; } - cshift = index % BIT_CHAR; - if (cshift > 0) { - mask = ~((~0) << (BIT_CHAR - cshift)); - cmask = cache & mask; - lshift = BIT_CHAR - cshift; - value <<= lshift; - value |= cmask; - // index += lshift; - currByte++; - } - for (; currByte < (endByte - 1); currByte++) { - value <<= BIT_CHAR; - value |= buf.get(currByte) & 0xFF; - } - lshift = end % BIT_CHAR; - if (lshift > 0) { - mask = ~((~0) << lshift); - cmask = buf.get(currByte) & 0xFF; - cmask >>>= BIT_CHAR - lshift; - cmask &= mask; - value <<= lshift; - value |= cmask; - } else { - value <<= BIT_CHAR; - value |= buf.get(currByte) & 0xFF; - } - return value; - } - private int getIntLE(int index, int length, boolean signed) { - assert ((length > 0) && (length <= BIT_INT)); - int end = index + length; - int startByte = index / BIT_CHAR; - int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; - int currByte, lshift, cshift, mask, cmask, cache, mod; - int value = 0; - - currByte = endByte - 1; - cache = buf.get(currByte) & 0xFF; - mod = end % BIT_CHAR; - lshift = (mod > 0) ? mod : BIT_CHAR; - boolean isNeg = (cache & (1 << (lshift - 1))) != 0; - if (signed && isNeg) { - value = ~0; - } - if (startByte == (endByte - 1)) { - cmask = cache >>> (index % BIT_CHAR); - if (((length) % BIT_CHAR) > 0) { - mask = ~((~0) << length); + private int getIntLE(int index, int length, boolean signed) { + assert ((length > 0) && (length <= BIT_INT)); + int end = index + length; + int startByte = index / BIT_CHAR; + int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; + int currByte, lshift, cshift, mask, cmask, cache, mod; + int value = 0; + + currByte = endByte - 1; + cache = buf.get(currByte) & 0xFF; + mod = end % BIT_CHAR; + lshift = (mod > 0) ? mod : BIT_CHAR; + boolean isNeg = (cache & (1 << (lshift - 1))) != 0; + if (signed && isNeg) { + value = ~0; + } + if (startByte == (endByte - 1)) { + cmask = cache >>> (index % BIT_CHAR); + if (((length) % BIT_CHAR) > 0) { + mask = ~((~0) << length); + cmask &= mask; + } + value <<= length; + value |= cmask; + return value; + } + cshift = end % BIT_CHAR; + if (cshift > 0) { + mask = ~((~0) << cshift); + cmask = cache & mask; + value <<= cshift; + value |= cmask; + // end -= cshift; + currByte--; + } + for (; currByte >= (startByte + 1); currByte--) { + value <<= BIT_CHAR; + value |= buf.get(currByte) & 0xFF; + } + lshift = index % BIT_CHAR; + if (lshift > 0) { + mask = ~((~0) << (BIT_CHAR - lshift)); + cmask = buf.get(currByte) & 0xFF; + cmask >>>= lshift; cmask &= mask; + value <<= (BIT_CHAR - lshift); + value |= cmask; + } else { + value <<= BIT_CHAR; + value |= buf.get(currByte) & 0xFF; } - value <<= length; - value |= cmask; return value; } - cshift = end % BIT_CHAR; - if (cshift > 0) { - mask = ~((~0) << cshift); - cmask = cache & mask; - value <<= cshift; - value |= cmask; - // end -= cshift; - currByte--; - } - for (; currByte >= (startByte + 1); currByte--) { - value <<= BIT_CHAR; - value |= buf.get(currByte) & 0xFF; - } - lshift = index % BIT_CHAR; - if (lshift > 0) { - mask = ~((~0) << (BIT_CHAR - lshift)); - cmask = buf.get(currByte) & 0xFF; - cmask >>>= lshift; - cmask &= mask; - value <<= (BIT_CHAR - lshift); - value |= cmask; - } else { - value <<= BIT_CHAR; - value |= buf.get(currByte) & 0xFF; - } - return value; - } - - // ------------------------------------------------------------------------ - // 'Put' operations on buffer - // ------------------------------------------------------------------------ - - /** - * Relative put method to write signed 32-bit integer. - * - * Write four bytes starting from current bit position in the buffer - * according to the current byte order. The current position is increased of - * length bits. - * - * @param value - * The int value to write - */ - public void putInt(int value) { - putInt(BIT_INT, value); - } - - /** - * Relative put method to write length bits integer. - * - * Writes length lower-order bits from the provided value, - * starting from current bit position in the buffer. Sequential bytes are - * written according to the current byte order. The sign bit is carried to - * the MSB if signed is true. The sign bit is included in length. The - * current position is increased of length. - * - * @param length - * The number of bits to write - * @param value - * The value to write - */ - public void putInt(int length, int value) { - putInt(this.pos, length, value); - } - /** - * Absolute put method to write length bits integer. - * - * Writes length lower-order bits from the provided value, - * starting from index position in the buffer. Sequential bytes are - * written according to the current byte order. The sign bit is carried to - * the MSB if signed is true. The sign bit is included in length. The - * current position is increased of length. - * - * @param index - * The start position to write the value - * @param value - * The value to write - * @param length - * The number of bits to write - */ - public void putInt(int index, int length, int value) { - if (!canRead(index, length)) { - throw new BufferOverflowException(); - } - if (length == 0) { - return; - } - if (byteOrder == ByteOrder.LITTLE_ENDIAN) { - putIntLE(index, length, value); - } else { - putIntBE(index, length, value); - } - } + // ------------------------------------------------------------------------ + // 'Put' operations on buffer + // ------------------------------------------------------------------------ - private void putIntBE(int index, int length, int value) { - assert ((length > 0) && (length <= BIT_INT)); - int end = index + length; - int startByte = index / BIT_CHAR; - int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; - int currByte, lshift, cshift, mask, cmask; - int correctedValue = value; - - /* - * mask v high bits. Works for unsigned and two complement signed - * numbers which value do not overflow on length bits. + /** + * Relative put method to write signed 32-bit integer. + * + * Write four bytes starting from current bit position in the buffer + * according to the current byte order. The current position is increased of + * length bits. + * + * @param value + * The int value to write + */ + public void putInt(int value) { + putInt(BIT_INT, value); + } + + /** + * Relative put method to write length bits integer. + * + * Writes length lower-order bits from the provided value, + * starting from current bit position in the buffer. Sequential bytes are + * written according to the current byte order. The sign bit is carried to + * the MSB if signed is true. The sign bit is included in length. The + * current position is increased of length. + * + * @param length + * The number of bits to write + * @param value + * The value to write */ + public void putInt(int length, int value) { + final int curPos = this.pos; - if (length < BIT_INT) { - correctedValue &= ~(~0 << length); + if (!canRead(length)) { + throw new BufferOverflowException(); + } + if (length == 0) { + return; + } + if (this.byteOrder == ByteOrder.LITTLE_ENDIAN) { + putIntLE(curPos, length, value); + } else { + putIntBE(curPos, length, value); + } + this.pos += length; } - /* sub byte */ - if (startByte == (endByte - 1)) { - lshift = (BIT_CHAR - (end % BIT_CHAR)) % BIT_CHAR; - mask = ~((~0) << lshift); - if ((index % BIT_CHAR) > 0) { - mask |= (~(0)) << (BIT_CHAR - (index % BIT_CHAR)); - } - cmask = correctedValue << lshift; + private void putIntBE(int index, int length, int value) { + assert ((length > 0) && (length <= BIT_INT)); + int end = index + length; + int startByte = index / BIT_CHAR; + int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; + int currByte, lshift, cshift, mask, cmask; + int correctedValue = value; + /* - * low bits are cleared because of lshift and high bits are already - * cleared + * mask v high bits. Works for unsigned and two complement signed + * numbers which value do not overflow on length bits. */ - cmask &= ~mask; - int b = buf.get(startByte) & 0xFF; - buf.put(startByte, (byte) ((b & mask) | cmask)); - return; - } - /* head byte contains MSB */ - currByte = endByte - 1; - cshift = end % BIT_CHAR; - if (cshift > 0) { - lshift = BIT_CHAR - cshift; - mask = ~((~0) << lshift); - cmask = correctedValue << lshift; - cmask &= ~mask; - int b = buf.get(currByte) & 0xFF; - buf.put(currByte, (byte) ((b & mask) | cmask)); - correctedValue >>>= cshift; - // end -= cshift; - currByte--; - } + if (length < BIT_INT) { + correctedValue &= ~(~0 << length); + } - /* middle byte(s) */ - for (; currByte >= (startByte + 1); currByte--) { - buf.put(currByte, (byte) correctedValue); - correctedValue >>>= BIT_CHAR; - } - /* end byte contains LSB */ - if ((index % BIT_CHAR) > 0) { - mask = (~0) << (BIT_CHAR - (index % BIT_CHAR)); - cmask = correctedValue & ~mask; - int b = buf.get(currByte) & 0xFF; - buf.put(currByte, (byte) ((b & mask) | cmask)); - } else { - buf.put(currByte, (byte) correctedValue); - } - } + /* sub byte */ + if (startByte == (endByte - 1)) { + lshift = (BIT_CHAR - (end % BIT_CHAR)) % BIT_CHAR; + mask = ~((~0) << lshift); + if ((index % BIT_CHAR) > 0) { + mask |= (~(0)) << (BIT_CHAR - (index % BIT_CHAR)); + } + cmask = correctedValue << lshift; + /* + * low bits are cleared because of lshift and high bits are already + * cleared + */ + cmask &= ~mask; + int b = this.buf.get(startByte) & 0xFF; + this.buf.put(startByte, (byte) ((b & mask) | cmask)); + return; + } - private void putIntLE(int index, int length, int value) { - assert ((length > 0) && (length <= BIT_INT)); - int end = index + length; - int startByte = index / BIT_CHAR; - int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; - int currByte, lshift, cshift, mask, cmask; - int correctedValue = value; - - /* - * mask v high bits. Works for unsigned and two complement signed - * numbers which value do not overflow on length bits. - */ + /* head byte contains MSB */ + currByte = endByte - 1; + cshift = end % BIT_CHAR; + if (cshift > 0) { + lshift = BIT_CHAR - cshift; + mask = ~((~0) << lshift); + cmask = correctedValue << lshift; + cmask &= ~mask; + int b = this.buf.get(currByte) & 0xFF; + this.buf.put(currByte, (byte) ((b & mask) | cmask)); + correctedValue >>>= cshift; + // end -= cshift; + currByte--; + } - if (length < BIT_INT) { - correctedValue &= ~(~0 << length); + /* middle byte(s) */ + for (; currByte >= (startByte + 1); currByte--) { + this.buf.put(currByte, (byte) correctedValue); + correctedValue >>>= BIT_CHAR; + } + /* end byte contains LSB */ + if ((index % BIT_CHAR) > 0) { + mask = (~0) << (BIT_CHAR - (index % BIT_CHAR)); + cmask = correctedValue & ~mask; + int b = this.buf.get(currByte) & 0xFF; + this.buf.put(currByte, (byte) ((b & mask) | cmask)); + } else { + this.buf.put(currByte, (byte) correctedValue); + } } - /* sub byte */ - if (startByte == (endByte - 1)) { - lshift = index % BIT_CHAR; - mask = ~((~0) << lshift); - if ((end % BIT_CHAR) > 0) { - mask |= (~(0)) << (end % BIT_CHAR); - } - cmask = correctedValue << lshift; + private void putIntLE(int index, int length, int value) { + assert ((length > 0) && (length <= BIT_INT)); + int end = index + length; + int startByte = index / BIT_CHAR; + int endByte = (end + (BIT_CHAR - 1)) / BIT_CHAR; + int currByte, lshift, cshift, mask, cmask; + int correctedValue = value; + /* - * low bits are cleared because of lshift and high bits are already - * cleared + * mask v high bits. Works for unsigned and two complement signed + * numbers which value do not overflow on length bits. */ - cmask &= ~mask; - int b = buf.get(startByte) & 0xFF; - buf.put(startByte, (byte) ((b & mask) | cmask)); - return; - } - /* head byte */ - currByte = startByte; - cshift = index % BIT_CHAR; - if (cshift > 0) { - mask = ~((~0) << cshift); - cmask = correctedValue << cshift; - cmask &= ~mask; - int b = buf.get(currByte) & 0xFF; - buf.put(currByte, (byte) ((b & mask) | cmask)); - correctedValue >>>= BIT_CHAR - cshift; - // index += BIT_CHAR - cshift; - currByte++; - } + if (length < BIT_INT) { + correctedValue &= ~(~0 << length); + } - /* middle byte(s) */ - for (; currByte < (endByte - 1); currByte++) { - buf.put(currByte, (byte) correctedValue); - correctedValue >>>= BIT_CHAR; - } - /* end byte */ - if ((end % BIT_CHAR) > 0) { - mask = (~0) << (end % BIT_CHAR); - cmask = correctedValue & ~mask; - int b = buf.get(currByte) & 0xFF; - buf.put(currByte, (byte) ((b & mask) | cmask)); - } else { - buf.put(currByte, (byte) correctedValue); + /* sub byte */ + if (startByte == (endByte - 1)) { + lshift = index % BIT_CHAR; + mask = ~((~0) << lshift); + if ((end % BIT_CHAR) > 0) { + mask |= (~(0)) << (end % BIT_CHAR); + } + cmask = correctedValue << lshift; + /* + * low bits are cleared because of lshift and high bits are already + * cleared + */ + cmask &= ~mask; + int b = this.buf.get(startByte) & 0xFF; + this.buf.put(startByte, (byte) ((b & mask) | cmask)); + return; + } + + /* head byte */ + currByte = startByte; + cshift = index % BIT_CHAR; + if (cshift > 0) { + mask = ~((~0) << cshift); + cmask = correctedValue << cshift; + cmask &= ~mask; + int b = this.buf.get(currByte) & 0xFF; + this.buf.put(currByte, (byte) ((b & mask) | cmask)); + correctedValue >>>= BIT_CHAR - cshift; + // index += BIT_CHAR - cshift; + currByte++; + } + + /* middle byte(s) */ + for (; currByte < (endByte - 1); currByte++) { + this.buf.put(currByte, (byte) correctedValue); + correctedValue >>>= BIT_CHAR; + } + /* end byte */ + if ((end % BIT_CHAR) > 0) { + mask = (~0) << (end % BIT_CHAR); + cmask = correctedValue & ~mask; + int b = this.buf.get(currByte) & 0xFF; + this.buf.put(currByte, (byte) ((b & mask) | cmask)); + } else { + this.buf.put(currByte, (byte) correctedValue); + } } - } - // ------------------------------------------------------------------------ - // Buffer attributes handling - // ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ + // Buffer attributes handling + // ------------------------------------------------------------------------ - /** - * Can this buffer be read for thus amount of bits? - * - * @param length - * the length in bits to read - * @return does the buffer have enough room to read the next "length" - */ - public boolean canRead(int length) { - return canRead(pos, length); - } + /** + * Can this buffer be read for thus amount of bits? + * + * @param length + * the length in bits to read + * @return does the buffer have enough room to read the next "length" + */ + public boolean canRead(int length) { + if (this.buf == null) { + return false; + } - /** - * Can this buffer be read for thus amount of bits? - * - * @param index - * the position in the buffer to read - * @param length - * the length in bits to read - * @return does the buffer have enough room to read the next "length" - */ - public boolean canRead(int index, int length) { - if (buf == null) { - return false; + if ((this.pos + length) > (this.buf.capacity() * BIT_CHAR)) { + return false; + } + return true; } - if ((index + length) > (buf.capacity() * BIT_CHAR)) { - return false; + /** + * Sets the order of the buffer. + * + * @param order + * The order of the buffer. + */ + public void setByteOrder(ByteOrder order) { + this.byteOrder = order; + if (this.buf != null) { + this.buf.order(order); + } } - return true; - } - /** - * Sets the order of the buffer. - * - * @param order - * The order of the buffer. - */ - public void order(ByteOrder order) { - this.byteOrder = order; - if (buf != null) { - buf.order(order); + /** + * Sets the order of the buffer. + * + * @return The order of the buffer. + */ + public ByteOrder getByteOrder() { + return this.byteOrder; } - } - /** - * Sets the order of the buffer. - * - * @return The order of the buffer. - */ - public ByteOrder order() { - return byteOrder; - } - - /** - * Sets the position in the buffer. - * - * @param newPosition - * The new position of the buffer. - */ - public void position(int newPosition) { - this.pos = newPosition; - } - - /** - * - * Sets the position in the buffer. - * - * @return order The position of the buffer. - */ - public int position() { - return pos; - } - - /** - * Sets the byte buffer - * - * @param buf - * the byte buffer - */ - public void setByteBuffer(ByteBuffer buf) { - this.buf = buf; - if (buf != null) { - this.buf.order(byteOrder); + /** + * Sets the position in the buffer. + * + * @param newPosition + * The new position of the buffer. + */ + public void position(int newPosition) { + this.pos = newPosition; } - clear(); - } - /** - * Gets the byte buffer - * - * @return The byte buffer - */ - public ByteBuffer getByteBuffer() { - return buf; - } + /** + * + * Sets the position in the buffer. + * + * @return order The position of the buffer. + */ + public int position() { + return this.pos; + } - /** - * Sets the byte order - * - * @param byteOrder - * The byte order - */ - public void setByteOrder(ByteOrder byteOrder) { - this.byteOrder = byteOrder; - } + /** + * Sets the byte buffer + * + * @param buf + * the byte buffer + */ + public void setByteBuffer(ByteBuffer buf) { + this.buf = buf; + if (buf != null) { + this.buf.order(this.byteOrder); + } + clear(); + } - /** - * Gets the byte order - * - * @return The byte order - */ - public ByteOrder getByteOrder() { - return byteOrder; - } + /** + * Gets the byte buffer + * + * @return The byte buffer + */ + public ByteBuffer getByteBuffer() { + return this.buf; + } - /** - * resets the bitbuffer. - */ - public void clear() { - position(0); + /** + * resets the bitbuffer. + */ + public void clear() { + position(0); - if (buf == null) { - return; + if (this.buf == null) { + return; + } + this.buf.clear(); } - buf.clear(); - } -} + } diff --git a/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/trace/StreamInput.java b/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/trace/StreamInput.java index 006ab8dc3f..b431a0fb88 100644 --- a/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/trace/StreamInput.java +++ b/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/trace/StreamInput.java @@ -189,7 +189,7 @@ public class StreamInput implements IDefinitionScope { * The BitBuffer to extract data from the StreamInput */ BitBuffer bitBuffer = new BitBuffer(); - bitBuffer.order(this.getStream().getTrace().getByteOrder()); + bitBuffer.setByteOrder(this.getStream().getTrace().getByteOrder()); /* * Create the definitions we need to read the packet headers + contexts @@ -223,7 +223,7 @@ public class StreamInput implements IDefinitionScope { long fileSize = getStreamSize(); if (currentPos < fileSize) { BitBuffer bitBuffer = new BitBuffer(); - bitBuffer.order(this.getStream().getTrace().getByteOrder()); + bitBuffer.setByteOrder(this.getStream().getTrace().getByteOrder()); StreamInputPacketIndexEntry packetIndex = new StreamInputPacketIndexEntry( currentPos); createPacketIndexEntry(fileSize, currentPos, packetIndex, -- 2.34.1