You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by mh...@apache.org on 2007/07/12 08:29:28 UTC
svn commit: r555505 - in /mina/trunk/core/src:
main/java/org/apache/mina/common/ByteBuffer.java
test/java/org/apache/mina/common/ByteBufferTest.java
Author: mheath
Date: Wed Jul 11 23:29:27 2007
New Revision: 555505
URL: http://svn.apache.org/viewvc?view=rev&rev=555505
Log:
Changed putEnumSet methods to accept Set<E> instead of EnumSet<E> for greater flexibility.
Added getter/putter methods for medium ints (3 byte ints).
Added tests for getter/putter medium int methods.
Modified:
mina/trunk/core/src/main/java/org/apache/mina/common/ByteBuffer.java
mina/trunk/core/src/test/java/org/apache/mina/common/ByteBufferTest.java
Modified: mina/trunk/core/src/main/java/org/apache/mina/common/ByteBuffer.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/ByteBuffer.java?view=diff&rev=555505&r1=555504&r2=555505
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/ByteBuffer.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/ByteBuffer.java Wed Jul 11 23:29:27 2007
@@ -33,12 +33,14 @@
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
+import java.nio.ReadOnlyBufferException;
import java.nio.ShortBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.util.EnumSet;
+import java.util.Set;
import org.apache.mina.common.support.ByteBufferHexDumper;
@@ -681,6 +683,175 @@
}
/**
+ * Relative <i>get</i> method for reading a medium int value.
+ *
+ * <p> Reads the next three bytes at this buffer's current position,
+ * composing them into an int value according to the current byte order,
+ * and then increments the position by three.</p>
+ *
+ * @return The medium int value at the buffer's current position
+ */
+ public int getMediumInt() {
+ byte b1 = get();
+ byte b2 = get();
+ byte b3 = get();
+ if (ByteOrder.BIG_ENDIAN.equals(order())) {
+ return getMediumInt(b1, b2, b3);
+ } else {
+ return getMediumInt(b3, b2, b1);
+ }
+ }
+
+ /**
+ * Relative <i>get</i> method for reading an unsigned medium int value.
+ *
+ * <p> Reads the next three bytes at this buffer's current position,
+ * composing them into an int value according to the current byte order,
+ * and then increments the position by three.</p>
+ *
+ * @return The unsigned medium int value at the buffer's current position
+ */
+ public int getUnsignedMediumInt() {
+ int b1 = getUnsigned();
+ int b2 = getUnsigned();
+ int b3 = getUnsigned();
+ if (ByteOrder.BIG_ENDIAN.equals(order())) {
+ return b1 << 16 | b2 << 8 | b3;
+ } else {
+ return b3 << 16 | b2 << 8 | b1;
+ }
+ }
+
+ /**
+ * Absolute <i>get</i> method for reading a medium int value.
+ *
+ * <p> Reads the next three bytes at this buffer's current position,
+ * composing them into an int value according to the current byte order.</p>
+ *
+ * @param index The index from which the medium int will be read
+ * @return The medium int value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public int getMediumInt(int index) {
+ byte b1 = get(index);
+ byte b2 = get(index + 1);
+ byte b3 = get(index + 2);
+ if (ByteOrder.BIG_ENDIAN.equals(order())) {
+ return getMediumInt(b1, b2, b3);
+ } else {
+ return getMediumInt(b3, b2, b1);
+ }
+ }
+
+ /**
+ * Absolute <i>get</i> method for reading an unsigned medium int value.
+ *
+ * <p> Reads the next three bytes at this buffer's current position,
+ * composing them into an int value according to the current byte order.</p>
+ *
+ * @param index The index from which the unsigned medium int will be read
+ * @return The unsigned medium int value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public int getUnsignedMediumInt(int index) {
+ int b1 = getUnsigned(index);
+ int b2 = getUnsigned(index + 1);
+ int b3 = getUnsigned(index + 2);
+ if (ByteOrder.BIG_ENDIAN.equals(order())) {
+ return b1 << 16 | b2 << 8 | b3;
+ } else {
+ return b3 << 16 | b2 << 8 | b1;
+ }
+ }
+
+ private int getMediumInt(byte b1, byte b2, byte b3) {
+ int ret = (b1 << 16 & 0xff0000) | (b2 << 8 & 0xff00) | (b3 & 0xff);
+ // Check to see if the medium int is negative (high bit in b1 set)
+ if ((b1 & 0x80) == 0x80) {
+ // Make the the whole int negative
+ ret |= 0xff000000;
+ }
+ return ret;
+ }
+
+ /**
+ * Relative <i>put</i> method for writing a medium int
+ * value.
+ *
+ * <p> Writes three bytes containing the given int value, in the
+ * current byte order, into this buffer at the current position, and then
+ * increments the position by three.</p>
+ *
+ * @param value
+ * The medium int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than three bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public ByteBuffer putMediumInt(int value) {
+ byte b1 = (byte)(value >> 16);
+ byte b2 = (byte)(value >> 8);
+ byte b3 = (byte)value;
+
+ if (ByteOrder.BIG_ENDIAN.equals(order())) {
+ put(b1).put(b2).put(b3);
+ } else {
+ put(b3).put(b2).put(b1);
+ }
+
+ return this;
+ }
+
+ /**
+ * Absolute <i>put</i> method for writing a medium int
+ * value.
+ *
+ * <p> Writes three bytes containing the given int value, in the
+ * current byte order, into this buffer at the given index.</p>
+ *
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The medium int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public ByteBuffer putMediumInt(int index, int value) {
+ byte b1 = (byte)(value >> 16);
+ byte b2 = (byte)(value >> 8);
+ byte b3 = (byte)value;
+
+ if (ByteOrder.BIG_ENDIAN.equals(order())) {
+ put(index, b1).put(index + 1, b2).put(index + 2, b3);
+ } else {
+ put(index, b3).put(index + 1, b2).put(index + 2, b1);
+ }
+
+ return this;
+ }
+
+ /**
* @see java.nio.ByteBuffer#putInt(int)
*/
public abstract ByteBuffer putInt( int value );
@@ -2222,12 +2393,12 @@
}
/**
- * Writes the specified {@link EnumSet} to the buffer as a byte sized bit vector.
+ * Writes the specified {@link Set} to the buffer as a byte sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSet(EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSet(Set<E> set) {
long vector = toLong(set);
if ((vector & ~BYTE_MASK) != 0) {
throw new IllegalArgumentException("The enum set is too large to fit in a byte: " + set);
@@ -2236,13 +2407,13 @@
}
/**
- * Writes the specified {@link EnumSet} to the buffer as a byte sized bit vector.
+ * Writes the specified {@link Set} to the buffer as a byte sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param index the index at which the byte will be written
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSet(int index, EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSet(int index, Set<E> set) {
long vector = toLong(set);
if ((vector & ~BYTE_MASK) != 0) {
throw new IllegalArgumentException("The enum set is too large to fit in a byte: " + set);
@@ -2251,12 +2422,12 @@
}
/**
- * Writes the specified {@link EnumSet} to the buffer as a short sized bit vector.
+ * Writes the specified {@link Set} to the buffer as a short sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSetShort(EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSetShort(Set<E> set) {
long vector = toLong(set);
if ((vector & ~SHORT_MASK) != 0) {
throw new IllegalArgumentException("The enum set is too large to fit in a short: " + set);
@@ -2265,13 +2436,13 @@
}
/**
- * Writes the specified {@link EnumSet} to the buffer as a short sized bit vector.
+ * Writes the specified {@link Set} to the buffer as a short sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param index the index at which the bytes will be written
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSetShort(int index, EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSetShort(int index, Set<E> set) {
long vector = toLong(set);
if ((vector & ~SHORT_MASK) != 0) {
throw new IllegalArgumentException("The enum set is too large to fit in a short: " + set);
@@ -2280,12 +2451,12 @@
}
/**
- * Writes the specified {@link EnumSet} to the buffer as an int sized bit vector.
+ * Writes the specified {@link Set} to the buffer as an int sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSetInt(EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSetInt(Set<E> set) {
long vector = toLong(set);
if ((vector & ~INT_MASK) != 0) {
throw new IllegalArgumentException("The enum set is too large to fit in an int: " + set);
@@ -2294,13 +2465,13 @@
}
/**
- * Writes the specified {@link EnumSet} to the buffer as an int sized bit vector.
+ * Writes the specified {@link Set} to the buffer as an int sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param index the index at which the bytes will be written
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSetInt(int index, EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSetInt(int index, Set<E> set) {
long vector = toLong(set);
if ((vector & ~INT_MASK) != 0) {
throw new IllegalArgumentException("The enum set is too large to fit in an int: " + set);
@@ -2309,30 +2480,30 @@
}
/**
- * Writes the specified {@link EnumSet} to the buffer as a long sized bit vector.
+ * Writes the specified {@link Set} to the buffer as a long sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSetLong(EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSetLong(Set<E> set) {
return putLong(toLong(set));
}
/**
- * Writes the specified {@link EnumSet} to the buffer as a long sized bit vector.
+ * Writes the specified {@link Set} to the buffer as a long sized bit vector.
*
- * @param <E> the enum type of the EnumSet
+ * @param <E> the enum type of the Set
* @param index the index at which the bytes will be written
* @param set the enum set to write to the buffer
*/
- public <E extends Enum<E>> ByteBuffer putEnumSetLong(int index, EnumSet<E> set) {
+ public <E extends Enum<E>> ByteBuffer putEnumSetLong(int index, Set<E> set) {
return putLong(index, toLong(set));
}
/**
- * Utility method for converting an EnumSet to a bit vector.
+ * Utility method for converting an Set to a bit vector.
*/
- private <E extends Enum<E>> long toLong(EnumSet<E> set) {
+ private <E extends Enum<E>> long toLong(Set<E> set) {
long vector = 0;
for (E e : set) {
if (e.ordinal() >= Long.SIZE) {
Modified: mina/trunk/core/src/test/java/org/apache/mina/common/ByteBufferTest.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/common/ByteBufferTest.java?view=diff&rev=555505&r1=555504&r2=555505
==============================================================================
--- mina/trunk/core/src/test/java/org/apache/mina/common/ByteBufferTest.java (original)
+++ mina/trunk/core/src/test/java/org/apache/mina/common/ByteBufferTest.java Wed Jul 11 23:29:27 2007
@@ -967,4 +967,72 @@
buf.flip();
assertEquals(TestEnum.E64, buf.getEnumInt(TestEnum.class));
}
+
+ public void testGetMediumInt() {
+ ByteBuffer buf = ByteBuffer.allocate(3);
+
+ buf.put((byte)0x01);
+ buf.put((byte)0x02);
+ buf.put((byte)0x03);
+ assertEquals(3, buf.position());
+
+ buf.flip();
+ assertEquals(0x010203, buf.getMediumInt());
+ assertEquals(0x010203, buf.getMediumInt(0));
+ buf.flip();
+ assertEquals(0x010203, buf.getUnsignedMediumInt());
+ assertEquals(0x010203, buf.getUnsignedMediumInt(0));
+ buf.flip();
+ assertEquals(0x010203, buf.getUnsignedMediumInt());
+ buf.flip().order(ByteOrder.LITTLE_ENDIAN);
+ assertEquals(0x030201, buf.getMediumInt());
+ assertEquals(0x030201, buf.getMediumInt(0));
+
+ // Test max medium int
+ buf.flip().order(ByteOrder.BIG_ENDIAN);
+ buf.put((byte)0x7f);
+ buf.put((byte)0xff);
+ buf.put((byte)0xff);
+ buf.flip();
+ assertEquals(0x7fffff, buf.getMediumInt());
+ assertEquals(0x7fffff, buf.getMediumInt(0));
+
+ // Test negative number
+ buf.flip().order(ByteOrder.BIG_ENDIAN);
+ buf.put((byte)0xff);
+ buf.put((byte)0x02);
+ buf.put((byte)0x03);
+ buf.flip();
+
+ assertEquals(0xffff0203, buf.getMediumInt());
+ assertEquals(0xffff0203, buf.getMediumInt(0));
+ buf.flip();
+
+ assertEquals(0x00ff0203, buf.getUnsignedMediumInt());
+ assertEquals(0x00ff0203, buf.getUnsignedMediumInt(0));
+ }
+
+ public void testPutMediumInt() {
+ ByteBuffer buf = ByteBuffer.allocate(3);
+
+ checkMediumInt(buf, 0);
+ checkMediumInt(buf, 1);
+ checkMediumInt(buf, -1);
+ checkMediumInt(buf, 0x7fffff);
+ }
+
+ private void checkMediumInt(ByteBuffer buf, int x) {
+ buf.putMediumInt(x);
+ assertEquals(3, buf.position());
+ buf.flip();
+ assertEquals(x, buf.getMediumInt());
+ assertEquals(3, buf.position());
+
+ buf.putMediumInt(0, x);
+ assertEquals(3, buf.position());
+ assertEquals(x, buf.getMediumInt(0));
+
+ buf.flip();
+ }
+
}