You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by jv...@apache.org on 2013/06/24 11:45:59 UTC
[1/2] git commit: Imporve IoBuffer
Updated Branches:
refs/heads/trunk ae054ee68 -> ca12d4855
Imporve IoBuffer
Squashed commit of the following:
commit 5fb7b37bcee6490ea9409843c4e81b4b25ab2324
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Mon Jun 24 07:03:54 2013 +0200
IoBuffer.compact() fix and dedicated test
commit 3462c4785a72b7dc77753ad12d76b3a27f10504e
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Mon Jun 24 01:43:54 2013 +0200
added a few tests for IoBuffer
commit c19c4917ca6fd62efdd4d128e2d400204fc253e2
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Mon Jun 24 01:43:26 2013 +0200
IoBuffer with some new features
commit 60d85e2dc000437c3b0d1d715cde8a5a83192d6d
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Sun Jun 23 23:16:19 2013 +0200
It is possible to set the position to the last index + 1 on a IoBuffer (like on java.nio.Buffer)
commit fbc4085eb446795c08f2693a75cd53ab7570ee7e
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Sun Jun 23 23:08:33 2013 +0200
IoBuffer's contains the available bytes of the ByteBuffers used for it's creation
commit 61b6b7431a637c89e3c0fda7c39ab32b9e169f21
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Sun Jun 23 23:06:11 2013 +0200
Endianness at the IoBuffer level
commit 5348a560805c53a4c5ead81c403d0b3348fa51eb
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Sun Jun 23 23:02:40 2013 +0200
mixed typed buffers should be handled by IoBuffers
commit 68c48c5e9b247b2e67dd551b67b8b8b113a6db81
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Sun Jun 23 22:51:22 2013 +0200
the endianness is handled at the IoBuffer level
commit 4e3f5a5d6e0627ee876514a6d3ff6e489f9529c3
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Sun Jun 23 22:38:52 2013 +0200
This test scenario doesn't match the array() specifications of the ByteBuffer class
commit a1c93c922d12b56459e6f8c53c2052c5805bcaf8
Author: Raphaël P. Barazzutti <ra...@gmail.com>
Date: Sun Jun 23 22:30:45 2013 +0200
when available it should return the array really backing the buffer
Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/527aa62e
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/527aa62e
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/527aa62e
Branch: refs/heads/trunk
Commit: 527aa62e5abcc6a3fe1f83cf56b721e58b23ecd9
Parents: ae054ee
Author: jvermillard <jv...@apache.org>
Authored: Mon Jun 24 11:44:21 2013 +0200
Committer: jvermillard <jv...@apache.org>
Committed: Mon Jun 24 11:44:21 2013 +0200
----------------------------------------------------------------------
.../java/org/apache/mina/codec/IoBuffer.java | 1234 +++++++++---------
.../org/apache/mina/codec/IoBufferTest.java | 230 +++-
2 files changed, 782 insertions(+), 682 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina/blob/527aa62e/codec/src/main/java/org/apache/mina/codec/IoBuffer.java
----------------------------------------------------------------------
diff --git a/codec/src/main/java/org/apache/mina/codec/IoBuffer.java b/codec/src/main/java/org/apache/mina/codec/IoBuffer.java
index b9b0864..8dcc7ec 100644
--- a/codec/src/main/java/org/apache/mina/codec/IoBuffer.java
+++ b/codec/src/main/java/org/apache/mina/codec/IoBuffer.java
@@ -18,7 +18,6 @@
*/
package org.apache.mina.codec;
-import java.nio.Buffer;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -32,265 +31,142 @@ import java.nio.ReadOnlyBufferException;
*
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
-public class IoBuffer {
- /** The list of ByteBuffers were we store the data */
- private BufferList buffers = new BufferList();
-
- /** The maximal position in the IoBuffer */
- private int limit;
-
- /** The current position in the buffer */
- private int position;
-
- /** The marked position, for the next reset() */
- private int mark;
-
- /** Tells if the stored buffers are direct or heap */
- private BufferType type;
-
- /** Tells if the IoBuffer is readonly */
- private boolean readOnly;
-
- /** The bytes order (BIG_INDIAN or LITTLE_INDIAN) */
- private ByteOrder order = ByteOrder.BIG_ENDIAN;
-
- /** The two types of buffer we handle */
- public enum BufferType {
- HEAP, DIRECT;
- }
-
- /** A empty bytes array */
- private static final byte[] EMPTY_BYTES = new byte[] {};
-
- /** <code>UNSET_MARK</code> means the mark has not been set. */
- private static final int UNSET_MARK = -1;
-
+public final class IoBuffer {
/**
- * Construct a IoBuffer, with no buffer in it
+ * @see ByteBuffer#allocate(int)
*/
- public IoBuffer() {
- position = 0;
- mark = 0;
- limit = 0;
- type = null;
- order = null;
+ public static IoBuffer allocate(int capacity) {
+ return new IoBuffer(ByteBuffer.allocate(capacity));
}
/**
- * Construct an empty IoBuffer with a defined type (either HEAP or DIRECT)
- *
- * @param bufferType the type of buffer to use : BufferType.HEAP or BufferType.DIRECT
+ * @see ByteBuffer#allocateDirect(int)
*/
- public IoBuffer(BufferType bufferType) {
- position = 0;
- mark = 0;
- limit = 0;
- type = bufferType;
+ public static IoBuffer allocateDirect(int capacity) {
+ return new IoBuffer(ByteBuffer.allocateDirect(capacity));
}
- /**
- * Construct a IoBuffer with some ByteBuffers. The IoBuffer type will be selected from the first ByteBuffer type, so
- * will the order.
- *
- * @param byteBuffers the ByteBuffers added to the IoBuffer list
- */
- public IoBuffer(ByteBuffer... byteBuffers) {
- if ((byteBuffers == null) || (byteBuffers.length == 0)) {
- position = 0;
- mark = 0;
- limit = 0;
- type = null;
- order = null;
- } else {
- for (ByteBuffer byteBuffer : byteBuffers) {
- if (type == null) {
- type = byteBuffer.isDirect() ? BufferType.DIRECT : BufferType.HEAP;
- }
-
- if (byteBuffer.limit() > 0) {
- buffers.add(byteBuffer);
- }
- }
- }
+ public static IoBuffer newInstance() {
+ return new IoBuffer();
}
/**
- * Construct a IoBuffer from an existing IoBuffer.
- *
- * @param ioBuffer the IoBuffer we want to copy
+ * @see ByteBuffer#wrap(byte[])
*/
- public IoBuffer(IoBuffer ioBuffer) {
- // Find the position to start with
- BufferNode node = ioBuffer.buffers.getFirst();
- int pos = 0;
-
- while (node != null) {
- if (node.offset + node.buffer.limit() < position) {
- node = buffers.getNext();
- pos = node.offset + node.buffer.limit();
- } else {
- buffers.add(node.buffer);
- }
+ public static IoBuffer wrap(byte[]... arrays) {
+ IoBuffer ioBuffer = new IoBuffer();
+ for (byte[] array : arrays) {
+ ioBuffer.add(ByteBuffer.wrap(array));
}
-
- position = position - pos;
- mark = 0;
- limit = ioBuffer.limit() - pos;
- type = ioBuffer.type;
- order = ioBuffer.order();
+ return ioBuffer;
}
/**
- * Adds a new ByteBuffer at the end of the list of buffers.
- *
- * @param byteBuffer The added ByteBuffer
- * @return The modified IoBuffer
+ * @see ByteBuffer#wrap(byte[], int, int)
*/
- public IoBuffer add(ByteBuffer... byteBuffers) {
- for (ByteBuffer byteBuffer : byteBuffers) {
- if (byteBuffer.limit() > 0) {
- buffers.add(byteBuffer);
- }
- }
+ public static IoBuffer wrap(byte[] array, int offset, int length) {
+ return new IoBuffer(ByteBuffer.wrap(array, offset, length));
+ }
- return this;
+ public static IoBuffer wrap(ByteBuffer... buffers) {
+ IoBuffer ioBuffer = new IoBuffer();
+ for (ByteBuffer b : buffers) {
+ ioBuffer.add(b);
+ }
+ return ioBuffer;
}
- /**
- * Allocate a Heap IoBuffer with a defined capacity
- *
- * @param capacity The number of bytes to store
- * @return The allocated IoBuffer
- */
- public static IoBuffer allocate(int capacity) {
- if (capacity >= 0) {
- ByteBuffer byteBuffer = ByteBuffer.allocate(capacity);
+ private ByteOrder bo = ByteOrder.BIG_ENDIAN;
- return new IoBuffer(byteBuffer);
- } else {
- throw new IllegalArgumentException("Cannot allocate an IoBuffer with a negative value : " + capacity);
- }
+ private int capacity = 0;
+
+ private boolean direct = true;
+
+ private BufferNode head, tail;
+
+ /** The maximal position in the IoBuffer */
+ private Pointer limit;
+
+ /** The current position in the buffer */
+ private Pointer mark;
+
+ /** The marked position, for the next reset() */
+ private Pointer position;
+
+ /** If the buffer is readonly */
+ private boolean readonly = false;
+
+ private IoBuffer() {
+ limit(0);
+ position(0);
+ mark = null;
}
- /**
- * Allocate a Direct IoBuffer with a defined capacity
- *
- * @param capacity The number of bytes to store
- * @return The allocated IoBuffer
- */
- public static IoBuffer allocateDirect(int capacity) {
- if (capacity >= 0) {
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(capacity);
+ //TODO set this method deprecated
+ // @Deprecated
+ public IoBuffer(ByteBuffer... buffers) {
+ this();
+ for (ByteBuffer b : buffers) {
+ add(b);
+ }
+ }
- return new IoBuffer(byteBuffer);
- } else {
- throw new IllegalArgumentException("Cannot allocate an IoBuffer with a negative value : " + capacity);
+ public IoBuffer add(ByteBuffer... buffers) {
+ for (ByteBuffer buffer : buffers) {
+ enqueue(buffer.slice());
}
+ return this;
}
/**
- * @see ByteBuffer#array() Returns the byte array which this IoBuffer is based on, up to the sum of each contained
- * ByteBuffer's limit().<br/>
- * This array can be modified, but this won't modify the content of the underlying ByteBuffer instances,
- * contrary to the ByteBuffer.array() method.
- *
- * @return the byte array which this IoBuffer is based on.
- * @exception ReadOnlyBufferException if this IoBuffer is based on a read-only array.
- * @exception UnsupportedOperationException if this IoBuffer is not based on an array.
+ * @see ByteBuffer#array()
*/
public byte[] array() {
- if (isReadOnly()) {
- throw new ReadOnlyBufferException();
+ if (capacity == 0) {
+ return new byte[0];
}
-
- if (buffers.size == 0) {
- return EMPTY_BYTES;
+ if (head.hasNext()) {
+ throw new UnsupportedOperationException();
}
-
- byte[] array = new byte[buffers.length];
- BufferNode node = buffers.getFirst();
- int pos = 0;
-
- while (node != null) {
- ByteBuffer buffer = node.buffer;
- byte[] src = buffer.array();
- int length = buffer.limit();
-
- System.arraycopy(src, 0, array, pos, length);
- pos += length;
-
- node = buffers.getNext();
- }
-
- return array;
+ return head.getBuffer().array();
}
/**
- * @see ByteBuffer#arrayOffset() Returns the offset of the byte array which this IoBuffer is based on, if there is
- * one.
- * <p>
- * The offset is the index of the array which corresponds to the zero position of the IoBuffer.
- *
- * @return the offset of the byte array which this IoBuffer is based on.
- * @exception ReadOnlyBufferException if this IoBuffer is based on a read-only array.
- * @exception UnsupportedOperationException if this IoBuffer is not based on an array.
+ * @see ByteBuffer#arrayOffset()
*/
public int arrayOffset() {
- if (isReadOnly()) {
- throw new ReadOnlyBufferException();
+ if (capacity == 0) {
+ return 0;
}
-
- // The offset is always 0
- return 0;
+ if (head.hasNext()) {
+ throw new UnsupportedOperationException();
+ }
+ return head.getBuffer().arrayOffset();
}
/**
* @see ByteBuffer#asReadOnlyBuffer()
*/
public IoBuffer asReadOnlyBuffer() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ IoBuffer buffer = duplicate();
+ buffer.readonly = true;
+ return buffer;
}
/**
- * @return the IoBuffer total capacity
+ * @see ByteBuffer#capacity()
*/
public int capacity() {
- return limit;
+ return capacity;
}
/**
- * @see Buffer#clear() Clears this IoBuffer.
- * <p>
- * the following internal changes take place:
- * <ul>
- * <li>the current position is reset back to the start of the buffer</li>
- * <li>the value of the buffer limit is made equal to the capacity</li>
- * <li>and mark is cleared</li>
- * </ul>
- * Note that the resulting IoBuffer might be wider than the original one, simply because we will extent the
- * ByteBuffers limit to their capacity.
- *
- * @return this buffer.
+ * @see ByteBuffer#clear()
*/
public IoBuffer clear() {
- position = 0;
- mark = UNSET_MARK;
-
- BufferNode node = buffers.head;
- int offset = 0;
-
- while (node != null) {
- node.buffer.clear();
- node.offset = offset;
- offset += node.buffer.limit();
- node = node.next;
- }
-
- limit = offset;
- buffers.length = 0;
- buffers.current = buffers.head;
-
+ position = getPointerByPosition(0);
+ limit = getPointerByPosition(capacity);
+ mark = null;
return this;
}
@@ -298,696 +174,756 @@ public class IoBuffer {
* @see ByteBuffer#compact()
*/
public IoBuffer compact() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ for (int i = 0; i < remaining(); i++) {
+ put(i, get(i + position.getPosition()));
+ }
+ position(limit() - position());
+ limit(capacity);
+ mark = null;
+ return this;
}
- /**
- * @see ByteBuffer#compareTo(ByteBuffer)
- */
- public int compareTo(IoBuffer buffer) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public IoBuffer duplicate() {
+ IoBuffer buffer = new IoBuffer();
+
+ for (BufferNode node = head; node != null; node = node.getNext()) {
+ ByteBuffer byteBuffer = node.getBuffer().duplicate();
+ byteBuffer.rewind();
+ buffer.enqueue(byteBuffer);
+ }
+ buffer.position(position());
+ buffer.limit(limit());
+ buffer.mark = mark != null ? getPointerByPosition(mark.getPosition()) : null;
+
+ buffer.readonly = readonly;
+ return buffer;
}
- /**
- * @see ByteBuffer#duplicate()
- */
- public IoBuffer duplicate() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ private void enqueue(ByteBuffer buffer) {
+
+ if (buffer.isReadOnly()) {
+ readonly = true;
+ }
+
+ if (!buffer.isDirect()) {
+ direct = false;
+ }
+ if (buffer.remaining() > 0) {
+ BufferNode newnode = new BufferNode(buffer, capacity);
+ capacity += buffer.capacity();
+
+ if (head == null) {
+ head = newnode;
+ position = getPointerByPosition(0);
+ } else {
+ tail.setNext(newnode);
+ }
+ tail = newnode;
+
+ limit = getPointerByPosition(capacity);
+ }
}
- /**
- * @see ByteBuffer#equals(Object)
- */
@Override
- public boolean equals(Object object) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public boolean equals(Object ob) {
+ if (this == ob) {
+ return true;
+ }
+ if (!(ob instanceof IoBuffer)) {
+ return false;
+ }
+ IoBuffer that = (IoBuffer) ob;
+ if (this.remaining() != that.remaining()) {
+ return false;
+ }
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {
+ if (this.get(i) != that.get(j)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public IoBuffer extend(int size) {
+ ByteBuffer extension = isDirect() ? ByteBuffer.allocateDirect(size) : ByteBuffer.allocate(size);
+ add(extension);
+ return this;
}
/**
- * @see Buffer#flip() Flips this buffer.
- * <p>
- * The limit is set to the current position, then the position is set to zero, and the mark is cleared.
- * <p>
- * The content of this IoBuffer is not changed.
- *
- * @return this IoBuffer.
+ * @see ByteBuffer#flip()
*/
public IoBuffer flip() {
limit = position;
- position = 0;
- mark = UNSET_MARK;
-
+ position = getPointerByPosition(0);
return this;
}
/**
- * Get a single byte for the IoBuffer at the current position. Increment the current position.
- *
- * @return The byte found a the current position.
+ * @see ByteBuffer#get()
*/
public byte get() {
- if (position >= limit) {
- // No more byte to read
+ if (position.getPosition() >= limit.getPosition()) {
throw new BufferUnderflowException();
}
- // find the byte from the current buffer now
- BufferNode currentNode = buffers.getCurrent();
-
- // If the position is within the current buffer, then get the data from it
- int bufferPosition = position - currentNode.offset;
-
- if (bufferPosition < currentNode.buffer.limit()) {
- position++;
-
- return currentNode.buffer.get();
- } else {
- // We have exhausted the current buffer, let's see if we have one more
- currentNode = buffers.getNext();
-
- if (currentNode == null) {
- // No more buffers
- throw new BufferUnderflowException();
- } else {
- position++;
- currentNode.buffer.position(0);
+ updatePosition();
+ position.setPosition(position.getPosition() + 1);
- return currentNode.buffer.get();
- }
- }
+ return position.getNode().getBuffer().get();
}
/**
- * @see ByteBuffer#get(byte[]) Reads bytes from the current position into the specified byte array and increases the
- * position by the number of bytes read.
- * <p>
- * Calling this method has the same effect as {@code get(dest, 0, dest.length)}.
- *
- * @param dest the destination byte array.
- * @return this IoBuffer.
- * @exception BufferUnderflowException if {@code dest.length} is greater than {@code remaining()}.
+ * @see ByteBuffer#get(byte[])
*/
public IoBuffer get(byte[] dst) {
- if (dst.length > remaining()) {
- throw new BufferUnderflowException();
- }
-
- int size = dst.length;
- int destPos = 0;
- BufferNode node = buffers.current;
-
- while (size > 0) {
- int length = node.buffer.limit() - node.buffer.position();
- System.arraycopy(node.buffer.array(), node.buffer.position(), dst, destPos, length);
- destPos += length;
- node = buffers.getNext();
- size -= length;
- }
-
+ get(dst, 0, dst.length);
return this;
}
/**
- * @see ByteBuffer#get(byte[],int,int)
+ * @see ByteBuffer#get(byte[], int,int)
*/
public IoBuffer get(byte[] dst, int offset, int length) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ if (remaining() < length) {
+ throw new BufferUnderflowException();
+ }
+
+ int remainsToCopy = length;
+ int currentOffset = offset;
+
+ while (remainsToCopy > 0) {
+ updatePosition();
+
+ ByteBuffer currentBuffer = position.getNode().getBuffer();
+ int blocksize = Math.min(remainsToCopy, currentBuffer.remaining());
+ position.getNode().getBuffer().get(dst, currentOffset, blocksize);
+
+ currentOffset += blocksize;
+ remainsToCopy -= blocksize;
+
+ position.setPosition(position.getPosition() + blocksize);
+ }
+ return this;
}
/**
- * @see ByteBuffer#get(int) Returns the byte at the specified index and does not change the position.
- *
- * @param index the index, must not be negative and less than limit.
- * @return the byte at the specified index.
- * @exception IndexOutOfBoundsException if index is invalid.
+ * @see ByteBuffer#get(int)
*/
- public byte get(int index) {
- if ((index < 0) || (index >= limit)) {
+ public byte get(int pos) {
+ if (pos >= limit.getPosition()) {
throw new IndexOutOfBoundsException();
}
+ BufferNode node = getBufferNodeByPosition(pos);
+ return node.getBuffer().get(pos - node.getOffset());
+ }
- BufferNode currentNode = buffers.current;
- BufferNode node = buffers.getFirst();
-
- while (node != null) {
- if (node.offset + node.buffer.limit() > index) {
- byte result = node.buffer.get(index - node.offset);
-
- // Reset the initial position before returning
- buffers.current = currentNode;
+ private BufferNode getBufferNodeByPosition(int pos) {
+ if (head == null) {
+ return null;
+ }
+ BufferNode currentNode = head;
+ int max = currentNode.getBuffer().capacity();
- return result;
- } else {
- node = buffers.getNext();
+ while (max <= pos && currentNode != null) {
+ currentNode = currentNode.getNext();
+ if (currentNode != null) {
+ max += currentNode.getBuffer().capacity();
}
}
- // Reset the initial position before returning
- buffers.current = currentNode;
-
- // Unlikely to happen
- throw new IndexOutOfBoundsException();
+ return currentNode;
}
/**
* @see ByteBuffer#getChar()
*/
- public IoBuffer getChar() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public char getChar() {
+ if (remaining() < 2) {
+ throw new BufferUnderflowException();
+ }
+ return (char) getShort();
}
/**
* @see ByteBuffer#getChar(int)
*/
- public IoBuffer getChar(int index) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public char getChar(int index) {
+ int oldPos = position();
+ position(index);
+ char out = getChar();
+ position(oldPos);
+ position.getNode().getBuffer().position(position.getPositionInNode());
+ return out;
}
/**
- * @see ByteBuffer#getDouble()
- */
- public IoBuffer getDouble() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ * @see ByteBuffer#getDouble()
+ */
+ public double getDouble() {
+ return Double.longBitsToDouble(getLong());
}
/**
* @see ByteBuffer#getDouble(int)
*/
- public IoBuffer getDouble(int index) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public double getDouble(int index) {
+ int oldPos = position();
+ position(index);
+ double out = getDouble();
+ position(oldPos);
+ position.getNode().getBuffer().position(position.getPositionInNode());
+ return out;
}
/**
* @see ByteBuffer#getFloat()
*/
- public IoBuffer getFloat() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public float getFloat() {
+ return Float.intBitsToFloat(getInt());
}
/**
* @see ByteBuffer#getFloat(int)
*/
- public IoBuffer getFloat(int index) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public float getFloat(int index) {
+ int oldPos = position();
+ position(index);
+ float out = getFloat();
+ position(oldPos);
+ return out;
}
/**
- * @see ByteBuffer#getInt() Returns the int at the current position and increases the position by 4.
- * <p>
- * The 4 bytes starting at the current position are composed into a int according to the current byte order and
- * returned.
- *
- * @return the int at the current position.
- * @exception BufferUnderflowException if the position is greater than {@code limit - 4}.
+ * @see ByteBuffer#getInt()
*/
public int getInt() {
- int newPosition = position + 4;
-
- if (newPosition > limit) {
+ if (remaining() < 4) {
throw new BufferUnderflowException();
}
- int result = loadInt(position);
- position = newPosition;
-
- return result;
- }
-
- /**
- * Load an int from the underlying byteBuffers, taking the order into account.
- */
- private int loadInt(int index) {
- int bytes = 0;
-
- if (order == ByteOrder.BIG_ENDIAN) {
- for (int i = 0; i < 4; i++) {
- bytes = bytes << 8;
- bytes = bytes | (get() & 0xFF);
- }
- } else {
- for (int i = 0; i < 4; i++) {
- int val = get() & 0xFF;
- bytes = bytes | (val << (i << 3));
- }
+ int out = 0;
+ for (int i = 0; i < 32; i += 8) {
+ out |= (get() & 0xff) << (bo == ByteOrder.BIG_ENDIAN ? 24 - i : i);
}
-
- return bytes;
+ return out;
}
/**
* @see ByteBuffer#getInt(int)
*/
- public IoBuffer getInt(int index) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public int getInt(int index) {
+ int oldPos = position();
+ position(index);
+ int out = getInt();
+ position(oldPos);
+ return out;
}
/**
* @see ByteBuffer#getLong()
*/
- public IoBuffer getLong() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public long getLong() {
+ if (remaining() < 8) {
+ throw new BufferUnderflowException();
+ }
+
+ long out = 0;
+ for (int i = 0; i < 64; i += 8) {
+ out |= (get() & 0xffl) << (bo == ByteOrder.BIG_ENDIAN ? 56 - i : i);
+ }
+ return out;
}
/**
* @see ByteBuffer#getLong(int)
*/
- public IoBuffer getLong(int index) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public long getLong(int index) {
+ int oldPos = position();
+ position(index);
+ long out = getLong();
+ position(oldPos);
+ return out;
+ }
+
+ private Pointer getPointerByPosition(int pos) {
+ if (pos == capacity) {
+ return new Pointer(tail, pos);
+ }
+
+ BufferNode currentNode = getBufferNodeByPosition(pos);
+ return new Pointer(currentNode, pos);
}
/**
* @see ByteBuffer#getShort()
*/
- public IoBuffer getShort() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public short getShort() {
+ if (remaining() < 2) {
+ throw new BufferUnderflowException();
+ }
+
+ if (bo == ByteOrder.BIG_ENDIAN) {
+ return (short) ((get() & 0xff) << 8 | (get() & 0xff));
+ } else {
+ return (short) ((get() & 0xff) | (get() & 0xff) << 8);
+ }
}
/**
* @see ByteBuffer#getShort(int)
*/
- public IoBuffer getShort(int index) {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public long getShort(int index) {
+ int oldPos = position();
+ position(index);
+ short out = getShort();
+ position(oldPos);
+ return out;
}
- /**
- * @see ByteBuffer#hashCode()
- */
@Override
public int hashCode() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ int hash = 0;
+ Pointer oldPos = position.duplicate();
+ while (hasRemaining()) {
+ hash *= 31;
+ hash += get();
+ }
+ position = oldPos;
+ return hash;
}
/**
- * @see Buffer#hasRemaining() Indicates if there are elements remaining in this IoBuffer, that is if
- * {@code position < limit}.
- *
- * @return {@code true} if there are elements remaining in this IoBuffer, {@code false} otherwise.
+ * @see ByteBuffer#hasRemaining()
*/
public boolean hasRemaining() {
- return position < limit;
+ return remaining() > 0;
}
/**
- * @see ByteBuffer#isDirect() Tells if the stored ByteBuffers are Direct buffers or Heap Buffers
- * @return <code>true</code> if we are storing Direct buffers, <code>false</code> otherwise.
+ * @see ByteBuffer#isDirect()
*/
public boolean isDirect() {
- return type == BufferType.DIRECT;
+ return direct;
}
/**
- * @see Buffer#isReadOnly() Indicates whether this IoBuffer is read-only.
- *
- * @return {@code true} if this IoBuffer is read-only, {@code false} otherwise.
+ * @see ByteBuffer#limit()
*/
- public boolean isReadOnly() {
- return readOnly;
+ public int limit() {
+ return limit.getPosition();
}
/**
- * @return the IoBuffer limit
+ * @see ByteBuffer#limit(int)
*/
- public int limit() {
- return limit;
+ public void limit(int limit) {
+ this.limit = getPointerByPosition(limit);
}
/**
- * @see Buffer#mark() Marks the current position, so that the position may return to this point later by calling
- * <code>reset()</code>.
- *
- * @return this IoBuffer.
+ * @see ByteBuffer#mark()
*/
- public IoBuffer mark() {
- mark = position;
-
- return this;
+ public void mark() {
+ this.limit = position.duplicate();
}
/**
- * @see ByteBuffer#order() Returns the byte order used by this Iouffer when converting bytes from/to other primitive
- * types.
- * <p>
- * The default byte order of byte buffer is always {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
+ * Returns the byte order used by this Iouffer when converting bytes from/to other primitive
+ * types.
+ * <p>
+ * The default byte order of byte buffer is always {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
*
* @return the byte order used by this IoBuffer when converting bytes from/to other primitive types.
+ *
+ * @see ByteBuffer#order()
*/
public ByteOrder order() {
- return order;
+ return bo;
}
/**
- * @see ByteBuffer#order(ByteOrder) Sets the byte order of this IoBuffer.
+ * Sets the byte order of this IoBuffer.
*
* @param byteOrder the byte order to set. If {@code null} then the order will be {@link ByteOrder#LITTLE_ENDIAN
* LITTLE_ENDIAN}.
* @return this IoBuffer.
- * @see ByteOrder
+ * @see ByteBuffer#order(ByteOrder)
*/
public IoBuffer order(ByteOrder bo) {
- if (bo == null) {
- order = ByteOrder.LITTLE_ENDIAN;
- } else {
- order = bo;
- }
+ this.bo = bo != null ? bo : ByteOrder.LITTLE_ENDIAN;
return this;
}
/**
- * @see Buffer#position()
- * @return The current position across all the ByteBuffers contained in the IoBuffer
+ * @see ByteBuffer#position()
*/
public int position() {
- return position;
+ return position.getPosition();
}
/**
- * @see Buffer#position(int) Sets the position in the IoBuffer.
- * <p>
- * If the mark is set and it is greater than the new position, then it is cleared.
- *
- * @param newPosition the new position, must be not negative and not greater than limit.
- * @return this IoBuffer.
- * @exception IllegalArgumentException if <code>newPosition</code> is invalid.
+ * @see ByteBuffer#position(int)
*/
- public IoBuffer position(int newPosition) {
- if (newPosition < 0) {
- throw new IllegalArgumentException("The new position(" + newPosition + ") is negative");
+ public void position(int position) {
+ if (position > limit() || position < 0) {
+ throw new IllegalArgumentException();
}
- if (newPosition >= limit) {
- throw new IllegalArgumentException("The new position(" + newPosition
- + ") is larger than this buffer limit (" + limit());
+ if (mark != null && mark.getPosition() > position) {
+ mark = null;
}
- if (buffers.head == null) {
- throw new IllegalArgumentException("Cannot set a position over an empty buffer");
+ setPosition(getPointerByPosition(position));
+ }
+
+ /**
+ * @see ByteBuffer#put(byte)
+ */
+ public IoBuffer put(byte b) {
+ if (readonly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (position.getPosition() >= limit.getPosition()) {
+ throw new BufferUnderflowException();
}
- // Find the right current buffer
- BufferNode currentNode = buffers.getCurrent();
+ updatePosition();
+ position.setPosition(position.getPosition() + 1);
- // The new position might not be on the current buffer.
- if ((newPosition < currentNode.offset) || (newPosition >= currentNode.offset + currentNode.buffer.limit())) {
- // Ok, we aren't on the current buffer. Find the new current buffer
- BufferNode node = buffers.head;
- int counter = 0;
+ position.getNode().getBuffer().put(b);
+ return this;
+ }
- while (node != null) {
- counter += node.buffer.limit();
+ /**
+ * @see ByteBuffer#put(byte[])
+ */
+ public IoBuffer put(byte[] dst) {
+ put(dst, 0, dst.length);
+ return this;
+ }
- if (counter >= newPosition) {
- // Found
- currentNode = node;
- break;
- } else {
- node = node.next;
- }
- }
+ /**
+ * @see ByteBuffer#put(byte[], int, int)
+ */
+ public IoBuffer put(byte[] dst, int offset, int length) {
+ if (readonly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (remaining() < length) {
+ throw new BufferUnderflowException();
}
- position = newPosition;
- currentNode.buffer.position(position - currentNode.offset);
- buffers.current = currentNode;
+ int remainsToCopy = length;
+ int currentOffset = offset;
+
+ while (remainsToCopy > 0) {
+ updatePosition();
+
+ ByteBuffer currentBuffer = position.getNode().getBuffer();
+ int blocksize = Math.min(remainsToCopy, currentBuffer.remaining());
+ position.getNode().getBuffer().put(dst, currentOffset, blocksize);
+
+ currentOffset += blocksize;
+ remainsToCopy -= blocksize;
+ position.setPosition(position.getPosition() + blocksize);
+ }
return this;
}
/**
- * @see Buffer#remaining() Returns the number of remaining elements in this IoBuffer, that is
- * {@code limit - position}.
- *
- * @return the number of remaining elements in this IoBuffer.
+ * @see ByteBuffer#put(int, byte)
*/
- public int remaining() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public IoBuffer put(int pos, byte value) {
+ if (pos >= limit.getPosition()) {
+ throw new IndexOutOfBoundsException();
+ }
+ BufferNode node = getBufferNodeByPosition(pos);
+ node.getBuffer().put(pos - node.getOffset(), value);
+ return this;
}
/**
- * @see Buffer#reset() Resets the position of this IoBuffer to the <code>mark</code>.
- *
- * @return this IoBuffer.
- * @exception InvalidMarkException if the mark is not set.
+ * @see ByteBuffer#putChar(char)
*/
- public IoBuffer reset() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public IoBuffer putChar(char value) {
+ if (remaining() < 2) {
+ throw new BufferUnderflowException();
+ }
+
+ putShort((short) value);
+ return this;
}
/**
- * @see Buffer#rewind() Rewinds this IoBuffer.
- * <p>
- * The position is set to zero, and the mark is cleared. The content of this IoBuffer is not changed.
- *
- * @return this IoBuffer.
+ * @see ByteBuffer#putChar(int, char)
*/
- public IoBuffer rewind() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public IoBuffer putChar(int index, char value) {
+ Pointer oldPos = position.duplicate();
+ position(index);
+ putChar(value);
+ position = oldPos;
+ return this;
}
/**
- * @see ByteBuffer#slice()
+ * @see ByteBuffer#putDouble(double)
*/
- public IoBuffer slice() {
- // TODO code me !
- throw new UnsupportedOperationException();
+ public IoBuffer putDouble(double value) {
+ return putLong(Double.doubleToLongBits(value));
}
/**
- * @see ByteBuffer#wrap(byte[])
+ * @see ByteBuffer#putDouble(int, double)
*/
- static public IoBuffer wrap(byte[] array) {
- return new IoBuffer(ByteBuffer.wrap(array));
+ public IoBuffer putDouble(int index, double value) {
+ int oldPos = position();
+ position(index);
+ putDouble(value);
+ position(oldPos);
+ return this;
}
/**
- * @see ByteBuffer#wrap(byte[], int, int)
+ * @see ByteBuffer#putFloat(float)
*/
- public IoBuffer wrap(byte[] array, int offset, int length) {
- return new IoBuffer(ByteBuffer.wrap(array, offset, length));
+ public IoBuffer putFloat(float value) {
+ return putLong(Float.floatToIntBits(value));
}
/**
- * Returns a string representing the IoBuffer.
- *
- * @return a String representation of the IoBuffer
+ * @see ByteBuffer#putFloat(int, float)
*/
- @Override
- public String toString() {
- return "IoBuffer[pos=" + position + " lim=" + limit + " mrk=" + mark + "]";
+ public IoBuffer putFloat(int index, float value) {
+ int oldPos = position();
+ position(index);
+ putFloat(value);
+ position(oldPos);
+ return this;
}
- // ------------------------------------------------------------------------------------------------
- // private inner data structure
- // ------------------------------------------------------------------------------------------------
/**
- * A container for ByterBuffers stored in the buffers list
+ * @see ByteBuffer#putInt(int)
*/
- private class BufferNode {
- /** The stored buffer */
- private ByteBuffer buffer;
+ public IoBuffer putInt(int value) {
+ if (remaining() < 4) {
+ throw new BufferUnderflowException();
+ }
- /** The next buffer in the list */
- private BufferNode next;
+ for (int i = 0; i < 32; i += 8) {
+ put((byte) (value >> (bo == ByteOrder.BIG_ENDIAN ? 24 - i : i)));
+ }
+ return this;
+ }
- /** The position of this buffer in the IoBuffer list of bytes */
- private int offset;
+ /**
+ * @see ByteBuffer#putInt(int, int)
+ */
+ public IoBuffer putInt(int index, int value) {
+ int oldPos = position();
+ position(index);
+ putInt(value);
+ position(oldPos);
+ return this;
+ }
- /**
- * Creates a new entry in the list
- *
- * @param entry The added ByteBuffer
- */
- private BufferNode(ByteBuffer byteBuffer) {
- this.buffer = byteBuffer;
+ /**
+ * @see ByteBuffer#putLong(long)
+ */
+ public IoBuffer putLong(long value) {
+ if (remaining() < 8) {
+ throw new BufferUnderflowException();
}
- @Override
- public String toString() {
- return buffer.toString() + ", Offset:" + offset + (next != null ? " --> \n " : "");
+ for (int i = 0; i < 64; i += 8) {
+ put((byte) (value >> (bo == ByteOrder.BIG_ENDIAN ? 56 - i : i)));
}
+
+ return this;
}
/**
- * A LinkedList storing all the ByteBuffers. It can only be browsed forward.
+ * @see ByteBuffer#putLong(int, int)
*/
- private class BufferList {
- /** The first ByteBuffer in the list */
- private BufferNode head;
-
- /** The last ByteBuffer in the list */
- private BufferNode tail;
+ public IoBuffer putLong(int index, long value) {
+ int oldPos = position();
+ position(index);
+ putLong(value);
+ position(oldPos);
+ return this;
+ }
- /** The current ByteBuffer in the list */
- private BufferNode current;
+ /**
+ * @see ByteBuffer#putShort(short)
+ */
+ public IoBuffer putShort(short value) {
+ if (remaining() < 2) {
+ throw new BufferUnderflowException();
+ }
- /** The number of nodes in the list */
- private int size;
+ for (int i = 0; i < 16; i += 8) {
+ put((byte) (value >> (bo == ByteOrder.BIG_ENDIAN ? 8 - i : i)));
+ }
+ return this;
+ }
- /** The number of bytes in the list */
- private int length;
+ /**
+ * @see ByteBuffer#putShort(int, short)
+ */
+ public IoBuffer putShort(int index, short value) {
+ int oldPos = position();
+ position(index);
+ putShort(value);
+ position(oldPos);
+ return this;
+ }
- /** A flag used to indicate that we already have navigated past the tail of the list. */
- private boolean pastTail;
+ /**
+ * @see ByteBuffer#remaining()
+ */
+ public int remaining() {
+ return limit() - position();
+ }
- /**
- * Creates an empty list
- */
- private BufferList() {
- head = tail = current = null;
- size = 0;
- length = 0;
- pastTail = false;
+ /**
+ * @see ByteBuffer#reset()
+ */
+ public IoBuffer reset() {
+ if (mark == null) {
+ throw new InvalidMarkException();
}
+ position = mark.duplicate();
+ return this;
+ }
- /**
- * Creates a list with one ByteBuffer
- *
- * @param byteBuffer The added ByteBuffer
- */
- private BufferList(ByteBuffer byteBuffer) {
- BufferNode node = new BufferNode(byteBuffer);
- head = tail = current = node;
- size = 1;
- length = byteBuffer.limit();
- pastTail = false;
- }
+ /**
+ * @see ByteBuffer#rewind()
+ */
+ public IoBuffer rewind() {
+ position(0);
+ mark = getPointerByPosition(-1);
+ return this;
+ }
- /**
- * Adds a new ByteBuffer in the list
- *
- * @param byteBuffer The added ByteBuffer
- */
- private void add(ByteBuffer byteBuffer) {
- assert (byteBuffer != null);
+ private void setPosition(Pointer position) {
+ this.position = position;
+ if (capacity > 0) {
+ position.getNode().getBuffer().position(position.getPositionInNode());
+ }
+ }
- // Check the buffer type
- if (type == null) {
- if (byteBuffer.isDirect()) {
- type = BufferType.DIRECT;
- } else {
- type = BufferType.HEAP;
- }
- } else {
- if (isDirect() != byteBuffer.isDirect()) {
- throw new RuntimeException();
+ /**
+ * @see ByteBuffer#slice()
+ */
+ public IoBuffer slice() {
+ updatePosition();
+ IoBuffer out = new IoBuffer();
+ out.order(order());
+
+ if (hasRemaining()) {
+ tail.getBuffer().limit(limit.getPositionInNode());
+ for (BufferNode node = position.getNode(); node != limit.getNode(); node = node.getNext()) {
+ if (node != head) {
+ node.getBuffer().position(0);
}
+ out.add(node.getBuffer());
}
-
- // Check the ByteOrder
- if (size == 0) {
- order = byteBuffer.order();
- } else if (order != byteBuffer.order()) {
- throw new RuntimeException();
+ if (tail != head) {
+ tail.getBuffer().position(0);
}
+ out.add(tail.getBuffer().slice());
+ tail.getBuffer().limit(tail.getBuffer().capacity());
+ }
- BufferNode newNode = new BufferNode(byteBuffer);
- newNode.offset = length;
-
- if (size == 0) {
- head = tail = current = newNode;
- } else {
- tail.next = newNode;
- tail = newNode;
- }
+ return out;
+ }
- size++;
- length += byteBuffer.limit();
- limit = length;
- pastTail = false;
+ private void updatePosition() {
+ while (!position.getNode().getBuffer().hasRemaining()) {
+ position.setNode(position.getNode().getNext());
+ position.getNode().getBuffer().rewind();
}
+ }
- /**
- * Get the first BufferNode in the list. The current pointer will move forward, after having be reset to the
- * beginning of the list
- *
- * @return The first BufferNode in the list
- */
- private BufferNode getFirst() {
- if (head == null) {
- return null;
- }
+ private static final class BufferNode {
+ private final ByteBuffer buffer;
- current = head.next;
- pastTail = false;
+ private BufferNode next;
- return head;
- }
+ private final int offset;
- /**
- * Get the next BufferNode from the list. If this is the first time this method is called, it will return the
- * same value than a getFirst().
- *
- * @return The next BufferNode in the list, moving forward in the list at the same time
- */
- private BufferNode getNext() {
- if (current == null) {
- return null;
- }
+ public BufferNode(ByteBuffer buffer, int offset) {
+ this.buffer = buffer;
+ this.offset = offset;
+ }
- if (current == tail) {
- if (pastTail) {
- return null;
- } else {
- pastTail = true;
+ public ByteBuffer getBuffer() {
+ return buffer;
+ }
- return current;
- }
- } else {
- current = current.next;
+ public BufferNode getNext() {
+ return next;
+ }
- return current;
- }
+ public int getOffset() {
+ return offset;
}
- /**
- * Gets the current BufferNode from the list, if we aren't already past the tail.
- *
- * @return The current BufferNode
- */
- private BufferNode getCurrent() {
- if (pastTail) {
- return null;
- }
+ public boolean hasNext() {
+ return next != null;
+ }
- return current;
+ public void setNext(BufferNode next) {
+ this.next = next;
}
@Override
public String toString() {
- StringBuilder sb = new StringBuilder();
+ return "BufferNode [offset=" + offset + ", buffer=" + buffer + "]";
+ }
+ }
- BufferNode node = head;
+ private static final class Pointer {
+ private BufferNode node;
- while (node != null) {
- if (node == current) {
- sb.append("**");
- }
+ private int position;
- sb.append(node);
- node = node.next;
- }
+ public Pointer(BufferNode node, int position) {
+ super();
+ this.node = node;
+ this.position = position;
+ }
+
+ public Pointer duplicate() {
+ return new Pointer(node, position);
+ }
+
+ public BufferNode getNode() {
+ return node;
+ }
- return sb.toString();
+ public int getPosition() {
+ return position;
+ }
+
+ public int getPositionInNode() {
+ return position - node.getOffset();
+ }
+
+ public void setNode(BufferNode node) {
+ this.node = node;
+ }
+
+ public void setPosition(int position) {
+ this.position = position;
+ }
+
+ @Override
+ public String toString() {
+ return "Pointer [node=" + node + ", position=" + position + "]";
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina/blob/527aa62e/codec/src/test/java/org/apache/mina/codec/IoBufferTest.java
----------------------------------------------------------------------
diff --git a/codec/src/test/java/org/apache/mina/codec/IoBufferTest.java b/codec/src/test/java/org/apache/mina/codec/IoBufferTest.java
index 7349eb8..399eeef 100644
--- a/codec/src/test/java/org/apache/mina/codec/IoBufferTest.java
+++ b/codec/src/test/java/org/apache/mina/codec/IoBufferTest.java
@@ -29,7 +29,6 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
-import org.apache.mina.codec.IoBuffer;
import org.junit.Test;
/**
@@ -114,7 +113,7 @@ public class IoBufferTest {
/**
* Test the addition of mixed type buffers
*/
- @Test(expected = RuntimeException.class)
+ @Test
public void testAddMixedTypeBuffers() {
ByteBuffer bb1 = ByteBuffer.allocate(5);
bb1.put("012".getBytes());
@@ -131,7 +130,7 @@ public class IoBufferTest {
/**
* Test the addition of mixed order buffers
*/
- @Test(expected = RuntimeException.class)
+ @Test
public void testAddMixedOrderBuffers() {
ByteBuffer bb1 = ByteBuffer.allocate(5);
bb1.order(ByteOrder.LITTLE_ENDIAN);
@@ -363,10 +362,9 @@ public class IoBufferTest {
ioBuffer = new IoBuffer(bb1);
- array = ioBuffer.array();
assertNotNull(array);
- assertEquals(3, array.length);
- assertTrue(Arrays.equals(new byte[] { '0', '1', '2' }, array));
+ assertEquals(5, array.length);
+ assertTrue(Arrays.equals(new byte[] { '0', '1', '2', 0, 0 }, array));
}
/**
@@ -384,29 +382,6 @@ public class IoBufferTest {
}
/**
- * Test the array method for a IoBuffer containing three ByteBuffers
- */
- @Test
- public void testArrayThreeByteBuffers() {
- ByteBuffer bb1 = ByteBuffer.allocate(5);
- bb1.put("012".getBytes());
- bb1.flip();
-
- ByteBuffer bb2 = ByteBuffer.allocate(0);
-
- ByteBuffer bb3 = ByteBuffer.allocate(5);
- bb3.put("3456".getBytes());
- bb3.flip();
-
- IoBuffer ioBuffer = new IoBuffer(bb1, bb2, bb3);
-
- byte[] array = ioBuffer.array();
- assertNotNull(array);
- assertEquals(7, array.length);
- assertTrue(Arrays.equals(new byte[] { '0', '1', '2', '3', '4', '5', '6' }, array));
- }
-
- /**
* Test the getInt() method, on a buffer containing 2 ints in one ByteBuffer
*/
@Test
@@ -457,6 +432,7 @@ public class IoBufferTest {
bb2.flip();
IoBuffer ioBuffer = new IoBuffer(bb1, bb2);
+ ioBuffer.order(ByteOrder.LITTLE_ENDIAN);
assertEquals(12345, ioBuffer.getInt());
assertEquals(67890, ioBuffer.getInt());
@@ -588,6 +564,8 @@ public class IoBufferTest {
// Move forward a bit
ioBuffer.get();
ioBuffer.get();
+
+ ioBuffer.limit(3);
// Clear
ioBuffer.clear();
@@ -595,8 +573,8 @@ public class IoBufferTest {
// We should be back to the origin
assertEquals(0, ioBuffer.position());
- // The limit must have grown
- assertEquals(8, ioBuffer.limit());
+ // The limit must back to the available size
+ assertEquals(6, ioBuffer.limit());
}
/**
@@ -686,7 +664,7 @@ public class IoBufferTest {
/**
* Test the position method over an emptyIoBuffer
*/
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void testPositionIntEmptyBuffer() {
IoBuffer ioBuffer = new IoBuffer();
@@ -735,7 +713,7 @@ public class IoBufferTest {
// The resulting buffer will be seen as "0123456789"
IoBuffer ioBuffer = new IoBuffer(bb1, bb2, bb3);
- ioBuffer.position(10);
+ ioBuffer.position(11);
}
/**
@@ -794,4 +772,190 @@ public class IoBufferTest {
assertEquals('0' + i, ioBuffer.get());
}
}
+
+ @Test
+ public void testSlice() {
+ ByteBuffer bb1 = ByteBuffer.allocate(5);
+ bb1.put("012".getBytes());
+ bb1.flip();
+
+ ByteBuffer bb2 = ByteBuffer.allocate(5);
+ bb2.put("345".getBytes());
+ bb2.flip();
+
+ ByteBuffer bb3 = ByteBuffer.allocate(5);
+ bb3.put("6789".getBytes());
+ bb3.flip();
+
+ IoBuffer ioBuffer = new IoBuffer();
+ ioBuffer.add(bb1, bb2).add(bb3);
+
+ ioBuffer.position(2);
+ ioBuffer.limit(8);
+
+ IoBuffer slice = ioBuffer.slice();
+
+ assertEquals(6, slice.remaining());
+ assertEquals(0, slice.position());
+ assertEquals(6, slice.limit());
+
+ byte seg[] = "234567".getBytes();
+ for (int i = 0; i < 6; i++) {
+ assertEquals(seg[i], slice.get(i));
+ }
+ }
+
+ @Test
+ public void testShort() {
+ for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
+ ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(3).order(bo).putShort((short) 12345).rewind();
+ IoBuffer ioBuffer = new IoBuffer(bb).order(bo);
+ assertEquals(3, ioBuffer.capacity());
+ ioBuffer.extend(1);
+ ioBuffer.position(2);
+ assertEquals(4, ioBuffer.capacity());
+ ioBuffer.putShort((short) -23456);
+ ioBuffer.rewind();
+ assertEquals(12345, ioBuffer.getShort());
+ assertEquals(-23456, ioBuffer.getShort());
+ }
+ }
+
+ @Test
+ public void testInt() {
+ for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
+ ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(5).order(bo).putInt(123456).rewind();
+ IoBuffer ioBuffer = new IoBuffer(bb).order(bo);
+ assertEquals(5, ioBuffer.capacity());
+ ioBuffer.extend(3);
+ ioBuffer.position(4);
+ assertEquals(8, ioBuffer.capacity());
+ ioBuffer.putInt(-23456789);
+ ioBuffer.rewind();
+ assertEquals(123456, ioBuffer.getInt());
+ assertEquals(-23456789, ioBuffer.getInt());
+ }
+ }
+
+ @Test
+ public void testLong() {
+ for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
+ ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(9).order(bo).putLong(123456789012l).rewind();
+ IoBuffer ioBuffer = new IoBuffer(bb).order(bo);
+ assertEquals(9, ioBuffer.capacity());
+ ioBuffer.extend(7);
+
+ ioBuffer.position(8);
+ assertEquals(16, ioBuffer.capacity());
+ ioBuffer.putLong(-23456789023l);
+ ioBuffer.rewind();
+ assertEquals(123456789012l, ioBuffer.getLong());
+ assertEquals(-23456789023l, ioBuffer.getLong());
+ }
+ }
+
+ @Test
+ public void testChar() {
+ for (ByteOrder bo : new ByteOrder[] { ByteOrder.BIG_ENDIAN, ByteOrder.LITTLE_ENDIAN }) {
+ ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(3).order(bo).putChar('ë').rewind();
+ IoBuffer ioBuffer = new IoBuffer(bb).order(bo);
+
+ assertEquals(3, ioBuffer.capacity());
+
+ ioBuffer.extend(1);
+ ioBuffer.order(bo);
+ ioBuffer.position(2);
+ assertEquals(4, ioBuffer.capacity());
+ ioBuffer.putChar('ü');
+ ioBuffer.rewind();
+
+ assertEquals('ë', ioBuffer.getChar());
+ assertEquals('ü', ioBuffer.getChar());
+ }
+ }
+
+ @Test
+ public void testGet() {
+ ByteBuffer bb1 = ByteBuffer.allocate(5);
+ bb1.put("012".getBytes());
+ bb1.flip();
+
+ ByteBuffer bb2 = ByteBuffer.allocate(5);
+ bb2.put("345".getBytes());
+ bb2.flip();
+
+ ByteBuffer bb3 = ByteBuffer.allocate(5);
+ bb3.put("6789".getBytes());
+ bb3.flip();
+
+ IoBuffer ioBuffer = new IoBuffer();
+ ioBuffer.add(bb1, bb2).add(bb3);
+
+ ioBuffer.position(2);
+ ioBuffer.limit(8);
+
+ byte block[] = new byte[6];
+ ioBuffer.get(block);
+ byte seg[] = "234567".getBytes();
+ for (int i = 0; i < 6; i++) {
+ assertEquals(seg[i], block[i]);
+ }
+ }
+
+ @Test
+ public void testPut() {
+ ByteBuffer bb1 = ByteBuffer.allocate(5);
+ bb1.put("012".getBytes());
+ bb1.flip();
+
+ ByteBuffer bb2 = ByteBuffer.allocate(5);
+ bb2.put("345".getBytes());
+ bb2.flip();
+
+ ByteBuffer bb3 = ByteBuffer.allocate(5);
+ bb3.put("6789".getBytes());
+ bb3.flip();
+
+ IoBuffer ioBuffer = new IoBuffer();
+ ioBuffer.add(bb1, bb2).add(bb3);
+
+ byte seq[] = "abcdefghij".getBytes();
+ ioBuffer.position(2);
+ ioBuffer.put(seq, 3, 3);
+ ioBuffer.rewind();
+ byte expected[] = "01def56789".getBytes();
+ for (int i = 0; i < 6; i++) {
+ assertEquals(expected[i], ioBuffer.get(i));
+ }
+ }
+
+ @Test
+ public void testCompact() {
+ ByteBuffer bb1 = ByteBuffer.allocate(5);
+ bb1.put("012".getBytes());
+ bb1.flip();
+
+ ByteBuffer bb2 = ByteBuffer.allocate(5);
+ bb2.put("345".getBytes());
+ bb2.flip();
+
+ ByteBuffer bb3 = ByteBuffer.allocate(5);
+ bb3.put("6789".getBytes());
+ bb3.flip();
+
+ IoBuffer ioBuffer = new IoBuffer();
+ ioBuffer.add(bb1, bb2).add(bb3);
+
+ ioBuffer.position(2);
+ ioBuffer.limit(8);
+
+ ioBuffer.compact();
+ assertEquals(ioBuffer.capacity(),ioBuffer.limit());
+ assertEquals(6,ioBuffer.position());
+
+ byte seg[] = "234567".getBytes();
+ for (int i = 0; i < 6; i++) {
+ assertEquals(seg[i], ioBuffer.get(i));
+ }
+ }
}
[2/2] git commit: removed reference to xbean
Posted by jv...@apache.org.
removed reference to xbean
Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/ca12d485
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/ca12d485
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/ca12d485
Branch: refs/heads/trunk
Commit: ca12d485509b788add0dc9a55b063586f5faf0a6
Parents: 527aa62
Author: jvermillard <jv...@apache.org>
Authored: Mon Jun 24 11:44:51 2013 +0200
Committer: jvermillard <jv...@apache.org>
Committed: Mon Jun 24 11:44:51 2013 +0200
----------------------------------------------------------------------
pom.xml | 12 ------------
1 file changed, 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina/blob/ca12d485/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index cf6bb90..1e3268f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -445,18 +445,6 @@
</plugin>
<plugin>
- <groupId>org.apache.xbean</groupId>
- <artifactId>maven-xbean-plugin</artifactId>
- <version>3.8</version>
- </plugin>
-
- <plugin>
- <groupId>org.apache.xbean</groupId>
- <artifactId>maven-xbean-plugin</artifactId>
- <version>3.8</version>
- </plugin>
-
- <plugin>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<version>1.5</version>