You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by tr...@apache.org on 2008/05/22 03:09:24 UTC
svn commit: r658963 - in /mina/branches/buffer/core/src:
main/java/org/apache/mina/util/byteaccess/ test/java/org/apache/mina/common/
Author: trustin
Date: Wed May 21 18:09:24 2008
New Revision: 658963
URL: http://svn.apache.org/viewvc?rev=658963&view=rev
Log:
Applied Rich's latest patch
Added:
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/AbstractByteArray.java (with props)
Modified:
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/BufferByteArray.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/ByteArray.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArray.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeBase.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeReader.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeWriter.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteReader.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteWriter.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeReader.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeWriter.java
mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/SimpleByteArrayFactory.java
mina/branches/buffer/core/src/test/java/org/apache/mina/common/ByteAccessTest.java
Added: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/AbstractByteArray.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/AbstractByteArray.java?rev=658963&view=auto
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/AbstractByteArray.java (added)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/AbstractByteArray.java Wed May 21 18:09:24 2008
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.util.byteaccess;
+
+
+abstract class AbstractByteArray implements ByteArray {
+
+ /**
+ * @inheritDoc
+ */
+ public final int length() {
+ return last() - first();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public final boolean equals(Object other) {
+ // Optimization: compare pointers.
+ if (other == this) {
+ return true;
+ }
+ // Compare types.
+ if (!(other instanceof ByteArray)) {
+ return false;
+ }
+ ByteArray otherByteArray = (ByteArray) other;
+ // Compare properties.
+ if (first() != otherByteArray.first()
+ || last() != otherByteArray.last()
+ || !order().equals(otherByteArray.order())) {
+ return false;
+ }
+ // Compare bytes.
+ Cursor cursor = cursor();
+ Cursor otherCursor = otherByteArray.cursor();
+ for (int remaining = cursor.getRemaining(); remaining > 0;) {
+ // Optimization: prefer int comparisons over byte comparisons
+ if (remaining >= 4) {
+ int i = cursor.getInt();
+ int otherI = otherCursor.getInt();
+ if (i != otherI) {
+ return false;
+ }
+ } else {
+ byte b = cursor.get();
+ byte otherB = otherCursor.get();
+ if (b != otherB) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+}
Propchange: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/AbstractByteArray.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/AbstractByteArray.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/BufferByteArray.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/BufferByteArray.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/BufferByteArray.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/BufferByteArray.java Wed May 21 18:09:24 2008
@@ -30,7 +30,7 @@
* a <code>SimpleByteArrayFactory</code>.
*
*/
-public abstract class BufferByteArray implements ByteArray {
+public abstract class BufferByteArray extends AbstractByteArray {
/**
* The backing <code>ByteBuffer</code>.
@@ -54,6 +54,27 @@
public ByteBuffer getSingleByteBuffer() {
return bb;
}
+
+ /**
+ * @inheritDoc
+ *
+ * Calling <code>free()</code> on the returned slice has no effect.
+ */
+ public ByteArray slice(int index, int length) {
+ int oldLimit = bb.limit();
+ bb.position(index);
+ bb.limit(index + length);
+ ByteBuffer slice = bb.slice();
+ bb.limit(oldLimit);
+ return new BufferByteArray(slice) {
+
+ @Override
+ public void free() {
+ // Do nothing.
+ }
+
+ };
+ }
/**
* @inheritDoc
@@ -91,13 +112,6 @@
/**
* @inheritDoc
*/
- public int length() {
- return last() - first();
- }
-
- /**
- * @inheritDoc
- */
public ByteOrder order() {
return bb.order();
}
@@ -142,6 +156,20 @@
/**
* @inheritDoc
*/
+ public short getShort(int index) {
+ return bb.getShort(index);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putShort(int index, short s) {
+ bb.putShort(index, s);
+ }
+
+ /**
+ * @inheritDoc
+ */
public int getInt(int index) {
return bb.getInt(index);
}
@@ -153,6 +181,62 @@
bb.putInt(index, i);
}
+ /**
+ * @inheritDoc
+ */
+ public long getLong(int index) {
+ return bb.getLong(index);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putLong(int index, long l) {
+ bb.putLong(index, l);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public float getFloat(int index) {
+ return bb.getFloat(index);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putFloat(int index, float f) {
+ bb.putFloat(index, f);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public double getDouble(int index) {
+ return bb.getDouble(index);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putDouble(int index, double d) {
+ bb.putDouble(index, d);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public char getChar(int index) {
+ return bb.getChar(index);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putChar(int index, char c) {
+ bb.putChar(index, c);
+ }
+
private class CursorImpl implements Cursor {
private int index;
@@ -195,6 +279,16 @@
}
this.index = index;
}
+
+ public void skip(int length) {
+ setIndex(index + length);
+ }
+
+ public ByteArray slice(int length) {
+ ByteArray slice = BufferByteArray.this.slice(index, length);
+ index += length;
+ return slice;
+ }
/**
* @inheritDoc
@@ -241,6 +335,23 @@
/**
* @inheritDoc
*/
+ public short getShort() {
+ short s = BufferByteArray.this.getShort(index);
+ index += 2;
+ return s;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putShort(short s) {
+ BufferByteArray.this.putShort(index, s);
+ index += 2;
+ }
+
+ /**
+ * @inheritDoc
+ */
public int getInt() {
int i = BufferByteArray.this.getInt(index);
index += 4;
@@ -255,5 +366,72 @@
index += 4;
}
+ /**
+ * @inheritDoc
+ */
+ public long getLong() {
+ long l = BufferByteArray.this.getLong(index);
+ index += 8;
+ return l;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putLong(long l) {
+ BufferByteArray.this.putLong(index, l);
+ index += 8;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public float getFloat() {
+ float f = BufferByteArray.this.getFloat(index);
+ index += 4;
+ return f;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putFloat(float f) {
+ BufferByteArray.this.putFloat(index, f);
+ index += 4;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public double getDouble() {
+ double d = BufferByteArray.this.getDouble(index);
+ index += 8;
+ return d;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putDouble(double d) {
+ BufferByteArray.this.putDouble(index, d);
+ index += 8;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public char getChar() {
+ char c = BufferByteArray.this.getChar(index);
+ index += 2;
+ return c;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putChar(char c) {
+ BufferByteArray.this.putChar(index, c);
+ index += 2;
+ }
}
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/ByteArray.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/ByteArray.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/ByteArray.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/ByteArray.java Wed May 21 18:09:24 2008
@@ -70,6 +70,13 @@
ByteBuffer getSingleByteBuffer();
/**
+ * A ByteArray is equal to another ByteArray if they start and end at the
+ * same index, have the same byte order, and contain the same bytes at each
+ * index.
+ */
+ public boolean equals(Object other);
+
+ /**
* @inheritDoc
*/
byte get(int index);
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArray.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArray.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArray.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArray.java Wed May 21 18:09:24 2008
@@ -30,8 +30,11 @@
/**
* A ByteArray composed of other ByteArrays. Optimised for fast relative access
* via cursors. Absolute access methods are provided, but may perform poorly.
+ *
+ * TODO: Write about laziness of cursor implementation - how movement doesn't
+ * happen until actual get/put.
*/
-public final class CompositeByteArray implements ByteArray {
+public final class CompositeByteArray extends AbstractByteArray {
/**
* Allows for efficient detection of component boundaries when using a cursor.
@@ -91,7 +94,7 @@
}
public void addFirst(ByteArray ba) {
- handleAdd(ba);
+ addHook(ba);
bas.addFirst(ba);
}
@@ -128,9 +131,9 @@
remaining -= component.last();
} else {
// Remove part of component. Do this by removing entire
- // component
- // then readding remaining bytes.
- // TODO: Consider using getByteBuffers(), as more generic.
+ // component then readding remaining bytes.
+ // TODO: Consider using getByteBuffers(), as would avoid
+ // performance problems for nested ComponentByteArrays.
ByteBuffer bb = component.getSingleByteBuffer();
int originalLimit = bb.limit();
bb.position(0);
@@ -163,7 +166,7 @@
}
public void addLast(ByteArray ba) {
- handleAdd(ba);
+ addHook(ba);
bas.addLast(ba);
}
@@ -280,6 +283,13 @@
public Cursor cursor(int index, CursorListener listener) {
return new CursorImpl(index, listener);
}
+
+ /**
+ * @inheritDoc
+ */
+ public ByteArray slice(int index, int length) {
+ return cursor(index).slice(length);
+ }
/**
* @inheritDoc
@@ -312,20 +322,6 @@
/**
* @inheritDoc
*/
- public int getInt(int index) {
- return cursor(index).getInt();
- }
-
- /**
- * @inheritDoc
- */
- public void putInt(int index, int i) {
- cursor(index).putInt(i);
- }
-
- /**
- * @inheritDoc
- */
public int first() {
return bas.firstByte();
}
@@ -338,13 +334,13 @@
}
/**
- * @inheritDoc
+ * This method should be called prior to adding any component
+ * <code>ByteArray</code> to a composite.
+ *
+ * @param ba
+ * The component to add.
*/
- public int length() {
- return last() - first();
- }
-
- private void handleAdd(ByteArray ba) {
+ private void addHook(ByteArray ba) {
// Check first() is zero, otherwise cursor might not work.
// TODO: Remove this restriction?
if (ba.first() != 0) {
@@ -387,6 +383,90 @@
}
}
+ /**
+ * @inheritDoc
+ */
+ public short getShort(int index) {
+ return cursor(index).getShort();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putShort(int index, short s) {
+ cursor(index).putShort(s);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public int getInt(int index) {
+ return cursor(index).getInt();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putInt(int index, int i) {
+ cursor(index).putInt(i);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public long getLong(int index) {
+ return cursor(index).getLong();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putLong(int index, long l) {
+ cursor(index).putLong(l);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public float getFloat(int index) {
+ return cursor(index).getFloat();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putFloat(int index, float f) {
+ cursor(index).putFloat(f);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public double getDouble(int index) {
+ return cursor(index).getDouble();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putDouble(int index, double d) {
+ cursor(index).putDouble(d);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public char getChar(int index) {
+ return cursor(index).getChar();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putChar(int index, char c) {
+ cursor(index).putChar(c);
+ }
+
private class CursorImpl implements Cursor {
private int index;
@@ -432,6 +512,30 @@
checkBounds(index, 0);
this.index = index;
}
+
+ /**
+ * @inheritDoc
+ */
+ public void skip(int length) {
+ setIndex(index + length);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public ByteArray slice(int length) {
+ CompositeByteArray slice = new CompositeByteArray(byteArrayFactory);
+ int remaining = length;
+ while (remaining > 0) {
+ prepareForAccess(remaining);
+ int componentSliceSize = Math.min(remaining, componentCursor.getRemaining());
+ ByteArray componentSlice = componentCursor.slice(componentSliceSize);
+ slice.addLast(componentSlice);
+ index += componentSliceSize;
+ remaining -= componentSliceSize;
+ }
+ return slice;
+ }
/**
* @inheritDoc
@@ -490,7 +594,7 @@
// Go forward, if necessary.
while (index >= componentIndex + componentNode.getByteArray()
- .last()) {
+ .length()) {
componentIndex += componentNode.getByteArray().last();
componentNode = componentNode.getNextNode();
if (listener != null) {
@@ -573,6 +677,49 @@
/**
* @inheritDoc
*/
+ public short getShort() {
+ prepareForAccess(2);
+ if (componentCursor.getRemaining() >= 4) {
+ short s = componentCursor.getShort();
+ index += 2;
+ return s;
+ } else {
+ byte b0 = get();
+ byte b1 = get();
+ if (order.equals(ByteOrder.BIG_ENDIAN)) {
+ return (short) ((b0 << 8) | (b1 << 0));
+ } else {
+ return (short) ((b1 << 8) | (b0 << 0));
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putShort(short s) {
+ prepareForAccess(2);
+ if (componentCursor.getRemaining() >= 4) {
+ componentCursor.putShort(s);
+ index += 2;
+ } else {
+ byte b0;
+ byte b1;
+ if (order.equals(ByteOrder.BIG_ENDIAN)) {
+ b0 = (byte) ((s >> 8) & 0xff);
+ b1 = (byte) ((s >> 0) & 0xff);
+ } else {
+ b0 = (byte) ((s >> 0) & 0xff);
+ b1 = (byte) ((s >> 8) & 0xff);
+ }
+ put(b0);
+ put(b1);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
public int getInt() {
prepareForAccess(4);
if (componentCursor.getRemaining() >= 4) {
@@ -580,14 +727,14 @@
index += 4;
return i;
} else {
+ byte b0 = get();
byte b1 = get();
byte b2 = get();
byte b3 = get();
- byte b4 = get();
if (order.equals(ByteOrder.BIG_ENDIAN)) {
- return b1 << 24 & b2 << 16 & b3 << 8 & b4;
+ return ((b0 << 24) | (b1 << 16) | (b2 << 8) | (b3 << 0));
} else {
- return b4 << 24 & b3 << 16 & b2 << 8 & b1;
+ return ((b3 << 24) | (b2 << 16) | (b1 << 8) | (b0 << 0));
}
}
}
@@ -601,32 +748,201 @@
componentCursor.putInt(i);
index += 4;
} else {
+ byte b0;
+ byte b1;
+ byte b2;
+ byte b3;
+ if (order.equals(ByteOrder.BIG_ENDIAN)) {
+ b0 = (byte) ((i >> 24) & 0xff);
+ b1 = (byte) ((i >> 16) & 0xff);
+ b2 = (byte) ((i >> 8) & 0xff);
+ b3 = (byte) ((i >> 0) & 0xff);
+ } else {
+ b0 = (byte) ((i >> 0) & 0xff);
+ b1 = (byte) ((i >> 8) & 0xff);
+ b2 = (byte) ((i >> 16) & 0xff);
+ b3 = (byte) ((i >> 24) & 0xff);
+ }
+ put(b0);
+ put(b1);
+ put(b2);
+ put(b3);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public long getLong() {
+ prepareForAccess(8);
+ if (componentCursor.getRemaining() >= 4) {
+ long l = componentCursor.getLong();
+ index += 8;
+ return l;
+ } else {
+ byte b0 = get();
+ byte b1 = get();
+ byte b2 = get();
+ byte b3 = get();
+ byte b4 = get();
+ byte b5 = get();
+ byte b6 = get();
+ byte b7 = get();
+ if (order.equals(ByteOrder.BIG_ENDIAN)) {
+ return ((b0 & 0xffL) << 56) | ((b1 & 0xffL) << 48) | ((b2 & 0xffL) << 40) | ((b3 & 0xffL) << 32) | ((b4 & 0xffL) << 24) | ((b5 & 0xffL) << 16) | ((b6 & 0xffL) << 8) | ((b7 & 0xffL) << 0);
+ } else {
+ return ((b7 & 0xffL) << 56) | ((b6 & 0xffL) << 48) | ((b5 & 0xffL) << 40) | ((b4 & 0xffL) << 32) | ((b3 & 0xffL) << 24) | ((b2 & 0xffL) << 16) | ((b1 & 0xffL) << 8) | ((b0 & 0xffL) << 0);
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putLong(long l) {
+ prepareForAccess(8);
+ if (componentCursor.getRemaining() >= 4) {
+ componentCursor.putLong(l);
+ index += 8;
+ } else {
+ byte b0;
byte b1;
byte b2;
byte b3;
byte b4;
+ byte b5;
+ byte b6;
+ byte b7;
if (order.equals(ByteOrder.BIG_ENDIAN)) {
- b4 = (byte) (i & 0xff);
- i >>= 8;
- b3 = (byte) (i & 0xff);
- i >>= 8;
- b2 = (byte) (i & 0xff);
- i >>= 8;
- b1 = (byte) (i & 0xff);
+ b0 = (byte) ((l >> 56) & 0xff);
+ b1 = (byte) ((l >> 48) & 0xff);
+ b2 = (byte) ((l >> 40) & 0xff);
+ b3 = (byte) ((l >> 32) & 0xff);
+ b4 = (byte) ((l >> 24) & 0xff);
+ b5 = (byte) ((l >> 16) & 0xff);
+ b6 = (byte) ((l >> 8) & 0xff);
+ b7 = (byte) ((l >> 0) & 0xff);
} else {
- b1 = (byte) (i & 0xff);
- i >>= 8;
- b2 = (byte) (i & 0xff);
- i >>= 8;
- b3 = (byte) (i & 0xff);
- i >>= 8;
- b4 = (byte) (i & 0xff);
+ b0 = (byte) ((l >> 0) & 0xff);
+ b1 = (byte) ((l >> 8) & 0xff);
+ b2 = (byte) ((l >> 16) & 0xff);
+ b3 = (byte) ((l >> 24) & 0xff);
+ b4 = (byte) ((l >> 32) & 0xff);
+ b5 = (byte) ((l >> 40) & 0xff);
+ b6 = (byte) ((l >> 48) & 0xff);
+ b7 = (byte) ((l >> 56) & 0xff);
}
+ put(b0);
put(b1);
put(b2);
put(b3);
put(b4);
+ put(b5);
+ put(b6);
+ put(b7);
}
}
+
+ /**
+ * @inheritDoc
+ */
+ public float getFloat() {
+ prepareForAccess(4);
+ if (componentCursor.getRemaining() >= 4) {
+ float f = componentCursor.getFloat();
+ index += 4;
+ return f;
+ } else {
+ int i = getInt();
+ return Float.intBitsToFloat(i);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putFloat(float f) {
+ prepareForAccess(4);
+ if (componentCursor.getRemaining() >= 4) {
+ componentCursor.putFloat(f);
+ index += 4;
+ } else {
+ int i = Float.floatToIntBits(f);
+ putInt(i);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public double getDouble() {
+ prepareForAccess(8);
+ if (componentCursor.getRemaining() >= 4) {
+ double d = componentCursor.getDouble();
+ index += 8;
+ return d;
+ } else {
+ long l = getLong();
+ return Double.longBitsToDouble(l);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putDouble(double d) {
+ prepareForAccess(8);
+ if (componentCursor.getRemaining() >= 4) {
+ componentCursor.putDouble(d);
+ index += 8;
+ } else {
+ long l = Double.doubleToLongBits(d);
+ putLong(l);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public char getChar() {
+ prepareForAccess(2);
+ if (componentCursor.getRemaining() >= 4) {
+ char c = componentCursor.getChar();
+ index += 2;
+ return c;
+ } else {
+ byte b0 = get();
+ byte b1 = get();
+ if (order.equals(ByteOrder.BIG_ENDIAN)) {
+ return (char) ((b0 << 8) | (b1 << 0));
+ } else {
+ return (char) ((b1 << 8) | (b0 << 0));
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putChar(char c) {
+ prepareForAccess(2);
+ if (componentCursor.getRemaining() >= 4) {
+ componentCursor.putChar(c);
+ index += 2;
+ } else {
+ byte b0;
+ byte b1;
+ if (order.equals(ByteOrder.BIG_ENDIAN)) {
+ b0 = (byte) ((c >> 8) & 0xff);
+ b1 = (byte) ((c >> 0) & 0xff);
+ } else {
+ b0 = (byte) ((c >> 0) & 0xff);
+ b1 = (byte) ((c >> 8) & 0xff);
+ }
+ put(b0);
+ put(b1);
+ }
+ }
+
}
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeBase.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeBase.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeBase.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeBase.java Wed May 21 18:09:24 2008
@@ -70,14 +70,23 @@
});
}
+ /**
+ * @inheritDoc
+ */
public final int getRemaining() {
return cursor.getRemaining();
}
+ /**
+ * @inheritDoc
+ */
public final boolean hasRemaining() {
return cursor.hasRemaining();
}
+ /**
+ * @inheritDoc
+ */
public ByteOrder order() {
return cba.order();
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeReader.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeReader.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeReader.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeReader.java Wed May 21 18:09:24 2008
@@ -50,6 +50,20 @@
cba.removeFirst().free();
}
}
+
+ /**
+ * @inheritDoc
+ */
+ public void skip(int length) {
+ cursor.skip(length);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public ByteArray slice(int length) {
+ return cursor.slice(length);
+ }
public byte get() {
return cursor.get();
@@ -58,9 +72,46 @@
public void get(ByteBuffer bb) {
cursor.get(bb);
}
+ /**
+ * @inheritDoc
+ */
+ public short getShort() {
+ return cursor.getShort();
+ }
+ /**
+ * @inheritDoc
+ */
public int getInt() {
return cursor.getInt();
}
+ /**
+ * @inheritDoc
+ */
+ public long getLong() {
+ return cursor.getLong();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public float getFloat() {
+ return cursor.getFloat();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public double getDouble() {
+ return cursor.getDouble();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public char getChar() {
+ return cursor.getChar();
+ }
+
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeWriter.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeWriter.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeWriter.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/CompositeByteArrayRelativeWriter.java Wed May 21 18:09:24 2008
@@ -126,11 +126,18 @@
ByteArray removed = cba.removeTo(index);
flusher.flush(removed);
}
+
+ /**
+ * @inheritDoc
+ */
+ public void skip(int length) {
+ cursor.skip(length);
+ }
@Override
protected void cursorPassedFirstComponent() {
if (autoFlush) {
- flushTo(cba.first() + cba.getFirst().last());
+ flushTo(cba.first() + cba.getFirst().length());
}
}
@@ -153,9 +160,48 @@
/**
* @inheritDoc
*/
+ public void putShort(short s) {
+ prepareForAccess(2);
+ cursor.putShort(s);
+ }
+
+ /**
+ * @inheritDoc
+ */
public void putInt(int i) {
prepareForAccess(4);
cursor.putInt(i);
}
+ /**
+ * @inheritDoc
+ */
+ public void putLong(long l) {
+ prepareForAccess(8);
+ cursor.putLong(l);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putFloat(float f) {
+ prepareForAccess(4);
+ cursor.putFloat(f);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putDouble(double d) {
+ prepareForAccess(8);
+ cursor.putDouble(d);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void putChar(char c) {
+ prepareForAccess(2);
+ cursor.putChar(c);
+ }
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteReader.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteReader.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteReader.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteReader.java Wed May 21 18:09:24 2008
@@ -43,10 +43,15 @@
int length();
/**
+ * Creates an array with a view of part of this array.
+ */
+ ByteArray slice(int index, int length);
+
+ /**
* Gets the order of the bytes.
*/
ByteOrder order();
-
+
/**
* Gets a <code>byte</code> from the given index.
*/
@@ -58,7 +63,32 @@
public void get(int index, ByteBuffer bb);
/**
+ * Gets a <code>short</code> from the given index.
+ */
+ short getShort(int index);
+
+ /**
* Gets an <code>int</code> from the given index.
*/
int getInt(int index);
+
+ /**
+ * Gets a <code>long</code> from the given index.
+ */
+ long getLong(int index);
+
+ /**
+ * Gets a <code>float</code> from the given index.
+ */
+ float getFloat(int index);
+
+ /**
+ * Gets a <code>double</code> from the given index.
+ */
+ double getDouble(int index);
+
+ /**
+ * Gets a <code>char</code> from the given index.
+ */
+ char getChar(int index);
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteWriter.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteWriter.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteWriter.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoAbsoluteWriter.java Wed May 21 18:09:24 2008
@@ -53,7 +53,32 @@
public void put(int index, ByteBuffer bb);
/**
+ * Puts a <code>short</code> at the given index.
+ */
+ void putShort(int index, short s);
+
+ /**
* Puts an <code>int</code> at the given index.
*/
void putInt(int index, int i);
+
+ /**
+ * Puts a <code>long</code> at the given index.
+ */
+ void putLong(int index, long l);
+
+ /**
+ * Puts a <code>float</code> at the given index.
+ */
+ void putFloat(int index, float f);
+
+ /**
+ * Puts a <code>double</code> at the given index.
+ */
+ void putDouble(int index, double d);
+
+ /**
+ * Puts a <code>char</code> at the given index.
+ */
+ void putChar(int index, char c);
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeReader.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeReader.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeReader.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeReader.java Wed May 21 18:09:24 2008
@@ -36,6 +36,16 @@
* Checks if there are any remaining bytes that can be read.
*/
boolean hasRemaining();
+
+ /**
+ * Advances the reader by the given number of bytes.
+ */
+ void skip(int length);
+
+ /**
+ * Creates an array with a view of part of this array.
+ */
+ ByteArray slice(int length);
/**
* Gets the order of the bytes.
@@ -53,8 +63,32 @@
void get(ByteBuffer bb);
/**
+ * Gets a <code>short</code> and advances the reader.
+ */
+ short getShort();
+
+ /**
* Gets an <code>int</code> and advances the reader.
*/
int getInt();
+ /**
+ * Gets a <code>long</code> and advances the reader.
+ */
+ long getLong();
+
+ /**
+ * Gets a <code>float</code> and advances the reader.
+ */
+ float getFloat();
+
+ /**
+ * Gets a <code>double</code> and advances the reader.
+ */
+ double getDouble();
+
+ /**
+ * Gets a <code>char</code> and advances the reader.
+ */
+ char getChar();
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeWriter.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeWriter.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeWriter.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/IoRelativeWriter.java Wed May 21 18:09:24 2008
@@ -36,6 +36,11 @@
* Checks if there are any remaining bytes that can be read.
*/
boolean hasRemaining();
+
+ /**
+ * Advances the writer by the given number of bytes.
+ */
+ void skip(int length);
/**
* Gets the order of the bytes.
@@ -53,7 +58,32 @@
void put(ByteBuffer bb);
/**
+ * Puts a <code>short</code> and advances the reader.
+ */
+ void putShort(short s);
+
+ /**
* Puts an <code>int</code> and advances the reader.
*/
void putInt(int i);
+
+ /**
+ * Puts a <code>long</code> and advances the reader.
+ */
+ void putLong(long l);
+
+ /**
+ * Puts a <code>float</code> and advances the reader.
+ */
+ void putFloat(float f);
+
+ /**
+ * Puts a <code>double</code> and advances the reader.
+ */
+ void putDouble(double d);
+
+ /**
+ * Puts a <code>char</code> and advances the reader.
+ */
+ void putChar(char c);
}
Modified: mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/SimpleByteArrayFactory.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/SimpleByteArrayFactory.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/SimpleByteArrayFactory.java (original)
+++ mina/branches/buffer/core/src/main/java/org/apache/mina/util/byteaccess/SimpleByteArrayFactory.java Wed May 21 18:09:24 2008
@@ -28,6 +28,10 @@
*/
public class SimpleByteArrayFactory implements ByteArrayFactory {
+ public SimpleByteArrayFactory() {
+ super();
+ }
+
/**
* @inheritDoc
*/
Modified: mina/branches/buffer/core/src/test/java/org/apache/mina/common/ByteAccessTest.java
URL: http://svn.apache.org/viewvc/mina/branches/buffer/core/src/test/java/org/apache/mina/common/ByteAccessTest.java?rev=658963&r1=658962&r2=658963&view=diff
==============================================================================
--- mina/branches/buffer/core/src/test/java/org/apache/mina/common/ByteAccessTest.java (original)
+++ mina/branches/buffer/core/src/test/java/org/apache/mina/common/ByteAccessTest.java Wed May 21 18:09:24 2008
@@ -1,8 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
package org.apache.mina.common;
-import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.createStrictControl;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
@@ -29,7 +49,7 @@
*/
public class ByteAccessTest extends TestCase {
- private final List<String> operations = new ArrayList<String>();
+ private List<String> operations = new ArrayList<String>();
private void resetOperations() {
operations.clear();
@@ -308,6 +328,44 @@
assertOperationCountEquals(1); // Frees ByteArray behind both buffers.
}
}
+
+ public void testCompositeByteArraySlicing() {
+ CompositeByteArray cba = new CompositeByteArray();
+ cba.addLast(getByteArrayFactory().create(10));
+ cba.addLast(getByteArrayFactory().create(10));
+ cba.addLast(getByteArrayFactory().create(10));
+ testByteArraySlicing(cba, 0, 30);
+ testByteArraySlicing(cba, 5, 10);
+ testByteArraySlicing(cba, 10, 20);
+ testByteArraySlicing(cba, 1, 28);
+ testByteArraySlicing(cba, 19, 2);
+ }
+
+ public void testBufferByteArraySlicing() {
+ ByteArray bba = getByteArrayFactory().create(30);
+ testByteArraySlicing(bba, 0, 30);
+ testByteArraySlicing(bba, 5, 10);
+ testByteArraySlicing(bba, 10, 20);
+ testByteArraySlicing(bba, 1, 28);
+ testByteArraySlicing(bba, 19, 2);
+
+ }
+
+ private void testByteArraySlicing(ByteArray ba, int start, int length) {
+ ByteArray slice = ba.slice(start, length);
+ for (int i = 0; i < length; i++) {
+ byte b1 = (byte) (i % 67);
+ byte b2 = (byte) (i % 36);
+ int sourceIndex = i + start;
+ int sliceIndex = i;
+ ba.put(sourceIndex, b1);
+ assertEquals(b1, ba.get(sourceIndex));
+ assertEquals(b1, slice.get(sliceIndex));
+ slice.put(sliceIndex, b2);
+ assertEquals(b2, ba.get(sourceIndex));
+ assertEquals(b2, slice.get(sliceIndex));
+ }
+ }
private ChunkedExpander getExpander(final int chunkSize) {
return new ChunkedExpander(getByteArrayFactory(), chunkSize) {
@@ -370,4 +428,84 @@
}
}
+ public void testByteArrayPrimitiveAccess() {
+ ByteArray bbaBig = getByteArrayFactory().create(1000);
+ bbaBig.order(ByteOrder.BIG_ENDIAN);
+ testPrimitiveAccess(bbaBig.cursor(), bbaBig.cursor());
+
+ ByteArray bbaLittle = getByteArrayFactory().create(1000);
+ bbaLittle.order(ByteOrder.LITTLE_ENDIAN);
+ testPrimitiveAccess(bbaLittle.cursor(), bbaLittle.cursor());
+ }
+
+ public void testCompositeByteArrayPrimitiveAccess() {
+ CompositeByteArray cbaBig = new CompositeByteArray();
+ cbaBig.order(ByteOrder.BIG_ENDIAN);
+ for (int i = 0; i < 1000; i++) {
+ ByteArray component = getByteArrayFactory().create(1);
+ component.order(ByteOrder.BIG_ENDIAN);
+ cbaBig.addLast(component);
+ }
+ testPrimitiveAccess(cbaBig.cursor(), cbaBig.cursor());
+
+ CompositeByteArray cbaLittle = new CompositeByteArray();
+ cbaLittle.order(ByteOrder.LITTLE_ENDIAN);
+ for (int i = 0; i < 1000; i++) {
+ ByteArray component = getByteArrayFactory().create(1);
+ component.order(ByteOrder.LITTLE_ENDIAN);
+ cbaLittle.addLast(component);
+ }
+ testPrimitiveAccess(cbaLittle.cursor(), cbaLittle.cursor());
+ }
+
+ public void testCompositeByteArrayWrapperPrimitiveAccess() {
+ CompositeByteArray cbaBig = new CompositeByteArray();
+ cbaBig.order(ByteOrder.BIG_ENDIAN);
+ for (int i = 0; i < 1000; i++) {
+ ByteArray component = getByteArrayFactory().create(1);
+ component.order(ByteOrder.BIG_ENDIAN);
+ cbaBig.addLast(component);
+ }
+ testPrimitiveAccess(new CompositeByteArrayRelativeWriter(cbaBig, getExpander(10), getFlusher(), false), new CompositeByteArrayRelativeReader(cbaBig, true));
+
+ CompositeByteArray cbaLittle = new CompositeByteArray();
+ cbaLittle.order(ByteOrder.LITTLE_ENDIAN);
+ for (int i = 0; i < 1000; i++) {
+ ByteArray component = getByteArrayFactory().create(1);
+ component.order(ByteOrder.LITTLE_ENDIAN);
+ cbaLittle.addLast(component);
+ }
+ testPrimitiveAccess(new CompositeByteArrayRelativeWriter(cbaLittle, getExpander(10), getFlusher(), false), new CompositeByteArrayRelativeReader(cbaLittle, true));
+ }
+
+ private void testPrimitiveAccess(IoRelativeWriter write, IoRelativeReader read) {
+ byte b = (byte) 0x12;
+ write.put(b);
+ assertEquals(b, read.get());
+
+ short s = (short) 0x12;
+ write.putShort(s);
+ assertEquals(s, read.getShort());
+
+ int i = 0x12345678;
+ write.putInt(i);
+ assertEquals(i, read.getInt());
+
+ long l = 0x1234567890123456L;
+ write.putLong(l);
+ assertEquals(l, read.getLong());
+
+ float f = Float.intBitsToFloat(i);
+ write.putFloat(f);
+ assertEquals(f, read.getFloat());
+
+ double d = Double.longBitsToDouble(l);
+ write.putDouble(d);
+ assertEquals(d, read.getDouble());
+
+ char c = (char) 0x1234;
+ write.putChar(c);
+ assertEquals(c, read.getChar());
+ }
+
}