Resolved issue: NETTY-278 ChannelBuffer.bytesBefore() as an alternative to indexOf()

* Added various bytesBefore() methods to ChannelBuffer
* Deprecated the methods that could be replaced by bytesBefore()
This commit is contained in:
Trustin Lee 2010-01-20 05:55:16 +00:00
parent fe73de3497
commit 5a897af28d
6 changed files with 208 additions and 46 deletions

View File

@ -583,6 +583,41 @@ public abstract class AbstractChannelBuffer implements ChannelBuffer {
return ChannelBuffers.indexOf(this, fromIndex, toIndex, indexFinder); return ChannelBuffers.indexOf(this, fromIndex, toIndex, indexFinder);
} }
public int bytesBefore(byte value) {
return bytesBefore(readerIndex(), readableBytes(), value);
}
public int bytesBefore(ChannelBufferIndexFinder indexFinder) {
return bytesBefore(readerIndex(), readableBytes(), indexFinder);
}
public int bytesBefore(int length, byte value) {
checkReadableBytes(length);
return bytesBefore(readerIndex(), length, value);
}
public int bytesBefore(int length, ChannelBufferIndexFinder indexFinder) {
checkReadableBytes(length);
return bytesBefore(readerIndex(), length, indexFinder);
}
public int bytesBefore(int index, int length, byte value) {
int endIndex = indexOf(index, index + length, value);
if (endIndex < 0) {
return -1;
}
return endIndex - index;
}
public int bytesBefore(int index, int length,
ChannelBufferIndexFinder indexFinder) {
int endIndex = indexOf(index, index + length, indexFinder);
if (endIndex < 0) {
return -1;
}
return endIndex - index;
}
@Override @Override
public int hashCode() { public int hashCode() {
return ChannelBuffers.hashCode(this); return ChannelBuffers.hashCode(this);

View File

@ -24,7 +24,6 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel; import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException; import java.nio.charset.UnsupportedCharsetException;
import java.util.NoSuchElementException;
/** /**
* A random and sequential accessible sequence of zero or more bytes (octets). * A random and sequential accessible sequence of zero or more bytes (octets).
@ -176,10 +175,13 @@ import java.util.NoSuchElementException;
* *
* <h3>Search operations</h3> * <h3>Search operations</h3>
* *
* Various {@code indexOf()} methods help you locate an index of a value which * Various {@link #indexOf(int, int, byte)} methods help you locate an index of
* meets a certain criteria. Complicated dynamic sequential search can be done * a value which meets a certain criteria. Complicated dynamic sequential
* with {@link ChannelBufferIndexFinder} as well as simple static single byte * search can be done with {@link ChannelBufferIndexFinder} as well as simple
* search. * static single byte search.
* <p>
* If you are decoding variable length data such as NUL-terminated string, you
* will find {@link #bytesBefore(byte)} also useful.
* *
* <h3>Mark and reset</h3> * <h3>Mark and reset</h3>
* *
@ -1080,20 +1082,9 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
ChannelBuffer readBytes(int length); ChannelBuffer readBytes(int length);
/** /**
* Transfers this buffer's data to a newly created buffer starting at * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #readBytes(int)} instead.
* the current {@code readerIndex} until the specified {@code indexFinder}
* returns {@code true} and increases the {@code readerIndex}
* by the number of the transferred bytes. The returned buffer's
* {@code readerIndex} and {@code writerIndex} are {@code 0} and
* the number of the transferred bytes respectively.
*
* @param indexFinder finds the end index of the sub-region
*
* @return the newly created buffer which contains the transferred bytes
*
* @throws NoSuchElementException
* if {@code indexFinder} didn't return {@code true} at all
*/ */
@Deprecated
ChannelBuffer readBytes(ChannelBufferIndexFinder indexFinder); ChannelBuffer readBytes(ChannelBufferIndexFinder indexFinder);
/** /**
@ -1111,17 +1102,9 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
ChannelBuffer readSlice(int length); ChannelBuffer readSlice(int length);
/** /**
* Returns a new slice of this buffer's sub-region starting at the current * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #readSlice(int)} instead.
* {@code readerIndex} and increases the {@code readerIndex} by the size
* of the new slice (determined by {@code indexFinder}).
*
* @param indexFinder finds the end index of the sub-region
*
* @return the newly created slice
*
* @throws NoSuchElementException
* if {@code indexFinder} didn't return {@code true} at all
*/ */
@Deprecated
ChannelBuffer readSlice(ChannelBufferIndexFinder indexFinder); ChannelBuffer readSlice(ChannelBufferIndexFinder indexFinder);
/** /**
@ -1246,14 +1229,9 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
void skipBytes(int length); void skipBytes(int length);
/** /**
* Increases the current {@code readerIndex} until the specified * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #skipBytes(int)} instead.
* {@code indexFinder} returns {@code true} in this buffer.
*
* @return the number of skipped bytes
*
* @throws NoSuchElementException
* if {@code firstIndexFinder} didn't return {@code true} at all
*/ */
@Deprecated
int skipBytes(ChannelBufferIndexFinder indexFinder); int skipBytes(ChannelBufferIndexFinder indexFinder);
/** /**
@ -1483,7 +1461,7 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
int indexOf(int fromIndex, int toIndex, byte value); int indexOf(int fromIndex, int toIndex, byte value);
/** /**
* Locates the first index where the specified {@code indexFinder} * Locates the first place where the specified {@code indexFinder}
* returns {@code true}. The search takes place from the specified * returns {@code true}. The search takes place from the specified
* {@code fromIndex} (inclusive) to the specified {@code toIndex} * {@code fromIndex} (inclusive) to the specified {@code toIndex}
* (exclusive). * (exclusive).
@ -1495,11 +1473,107 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
* this buffer. * this buffer.
* *
* @return the absolute index where the specified {@code indexFinder} * @return the absolute index where the specified {@code indexFinder}
* returned {@code true} if the {@code indexFinder} returned * returned {@code true}. {@code -1} if the {@code indexFinder}
* {@code true}. {@code -1} otherwise. * did not return {@code true} at all.
*/ */
int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder); int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder);
/**
* Locates the first occurrence of the specified {@code value} in this
* buffer. The search takes place from the current {@code readerIndex}
* (inclusive) to the current {@code writerIndex} (exclusive).
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first occurrence if found. {@code -1} otherwise.
*/
int bytesBefore(byte value);
/**
* Locates the first place where the specified {@code indexFinder} returns
* {@code true}. The search takes place from the current {@code readerIndex}
* (inclusive) to the current {@code writerIndex}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first place where the {@code indexFinder} returned
* {@code true}. {@code -1} if the {@code indexFinder} did not
* return {@code true} at all.
*/
int bytesBefore(ChannelBufferIndexFinder indexFinder);
/**
* Locates the first occurrence of the specified {@code value} in this
* buffer. The search starts from the current {@code readerIndex}
* (inclusive) and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first occurrence if found. {@code -1} otherwise.
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
int bytesBefore(int length, byte value);
/**
* Locates the first place where the specified {@code indexFinder} returns
* {@code true}. The search starts the current {@code readerIndex}
* (inclusive) and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the current {@code readerIndex}
* and the first place where the {@code indexFinder} returned
* {@code true}. {@code -1} if the {@code indexFinder} did not
* return {@code true} at all.
*
* @throws IndexOutOfBoundsException
* if {@code length} is greater than {@code this.readableBytes}
*/
int bytesBefore(int length, ChannelBufferIndexFinder indexFinder);
/**
* Locates the first occurrence of the specified {@code value} in this
* buffer. The search starts from the specified {@code index} (inclusive)
* and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the specified {@code index}
* and the first occurrence if found. {@code -1} otherwise.
*
* @throws IndexOutOfBoundsException
* if {@code index + length} is greater than {@code this.capacity}
*/
int bytesBefore(int index, int length, byte value);
/**
* Locates the first place where the specified {@code indexFinder} returns
* {@code true}. The search starts the specified {@code index} (inclusive)
* and lasts for the specified {@code length}.
* <p>
* This method does not modify {@code readerIndex} or {@code writerIndex} of
* this buffer.
*
* @return the number of bytes between the specified {@code index}
* and the first place where the {@code indexFinder} returned
* {@code true}. {@code -1} if the {@code indexFinder} did not
* return {@code true} at all.
*
* @throws IndexOutOfBoundsException
* if {@code index + length} is greater than {@code this.capacity}
*/
int bytesBefore(int index, int length, ChannelBufferIndexFinder indexFinder);
/** /**
* Returns a copy of this buffer's readable bytes. Modifying the content * Returns a copy of this buffer's readable bytes. Modifying the content
* of the returned buffer or this buffer does not affect each other at all. * of the returned buffer or this buffer does not affect each other at all.
@ -1636,20 +1710,20 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
String toString(String charsetName); String toString(String charsetName);
/** /**
* @deprecated Use {@link #toString(int, int, Charset)} instead. * @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
*/ */
@Deprecated @Deprecated
String toString( String toString(
String charsetName, ChannelBufferIndexFinder terminatorFinder); String charsetName, ChannelBufferIndexFinder terminatorFinder);
/** /**
* @deprecated Use {@link #toString(int, int, Charset)} instead. * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
*/ */
@Deprecated @Deprecated
String toString(int index, int length, String charsetName); String toString(int index, int length, String charsetName);
/** /**
* @deprecated Use {@link #toString(int, int, Charset)} instead. * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
*/ */
@Deprecated @Deprecated
String toString( String toString(

View File

@ -21,10 +21,8 @@ package org.jboss.netty.buffer;
* <p> * <p>
* This interface enables the sequential search for the data which meets more * This interface enables the sequential search for the data which meets more
* complex and dynamic condition than just a simple value matching. Please * complex and dynamic condition than just a simple value matching. Please
* refer to {@link ChannelBuffer#indexOf(int, int, ChannelBufferIndexFinder)}, * refer to {@link ChannelBuffer#indexOf(int, int, ChannelBufferIndexFinder)} and
* {@link ChannelBuffer#readBytes(ChannelBufferIndexFinder)}, * {@link ChannelBuffer#bytesBefore(int, int, ChannelBufferIndexFinder)}
* {@link ChannelBuffer#readSlice(ChannelBufferIndexFinder)}, and
* {@link ChannelBuffer#skipBytes(ChannelBufferIndexFinder)}
* for more explanation. * for more explanation.
* *
* @author The Netty Project (netty-dev@lists.jboss.org) * @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -223,6 +223,57 @@ class ReplayingDecoderBuffer implements ChannelBuffer {
return endIndex; return endIndex;
} }
public int bytesBefore(byte value) {
int bytes = buffer.bytesBefore(value);
if (bytes < 0) {
throw REPLAY;
}
return bytes;
}
public int bytesBefore(ChannelBufferIndexFinder indexFinder) {
int bytes = buffer.bytesBefore(indexFinder);
if (bytes < 0) {
throw REPLAY;
}
return bytes;
}
public int bytesBefore(int length, byte value) {
checkReadableBytes(length);
int bytes = buffer.bytesBefore(length, value);
if (bytes < 0) {
throw REPLAY;
}
return bytes;
}
public int bytesBefore(int length, ChannelBufferIndexFinder indexFinder) {
checkReadableBytes(length);
int bytes = buffer.bytesBefore(length, indexFinder);
if (bytes < 0) {
throw REPLAY;
}
return bytes;
}
public int bytesBefore(int index, int length, byte value) {
int bytes = buffer.bytesBefore(index, length, value);
if (bytes < 0) {
throw REPLAY;
}
return bytes;
}
public int bytesBefore(int index, int length,
ChannelBufferIndexFinder indexFinder) {
int bytes = buffer.bytesBefore(index, length, indexFinder);
if (bytes < 0) {
throw REPLAY;
}
return bytes;
}
public void markReaderIndex() { public void markReaderIndex() {
buffer.markReaderIndex(); buffer.markReaderIndex();
} }

View File

@ -1199,6 +1199,7 @@ public abstract class AbstractChannelBufferTest {
} }
@Test @Test
@SuppressWarnings("deprecation")
public void testSequentialCopiedBufferTransfer2() { public void testSequentialCopiedBufferTransfer2() {
buffer.clear(); buffer.clear();
buffer.writeZero(buffer.capacity()); buffer.writeZero(buffer.capacity());
@ -1249,6 +1250,7 @@ public abstract class AbstractChannelBufferTest {
} }
@Test @Test
@SuppressWarnings("deprecation")
public void testSequentialSlice2() { public void testSequentialSlice2() {
buffer.clear(); buffer.clear();
buffer.writeZero(buffer.capacity()); buffer.writeZero(buffer.capacity());
@ -1641,6 +1643,7 @@ public abstract class AbstractChannelBufferTest {
} }
@Test @Test
@SuppressWarnings("deprecation")
public void testSkipBytes2() { public void testSkipBytes2() {
buffer.clear(); buffer.clear();
buffer.writeZero(buffer.capacity()); buffer.writeZero(buffer.capacity());

View File

@ -63,7 +63,8 @@ public class ReplayingDecoderTest {
@Override @Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer buffer, VoidEnum state) throws Exception { ChannelBuffer buffer, VoidEnum state) throws Exception {
ChannelBuffer msg = buffer.readBytes(ChannelBufferIndexFinder.LF); ChannelBuffer msg = buffer.readBytes(
buffer.bytesBefore(ChannelBufferIndexFinder.LF));
buffer.skipBytes(1); buffer.skipBytes(1);
return msg; return msg;
} }