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);
}
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
public int hashCode() {
return ChannelBuffers.hashCode(this);

View File

@ -24,7 +24,6 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.NoSuchElementException;
/**
* A random and sequential accessible sequence of zero or more bytes (octets).
@ -176,10 +175,13 @@ import java.util.NoSuchElementException;
*
* <h3>Search operations</h3>
*
* Various {@code indexOf()} methods help you locate an index of a value which
* meets a certain criteria. Complicated dynamic sequential search can be done
* with {@link ChannelBufferIndexFinder} as well as simple static single byte
* search.
* Various {@link #indexOf(int, int, byte)} methods help you locate an index of
* a value which meets a certain criteria. Complicated dynamic sequential
* search can be done with {@link ChannelBufferIndexFinder} as well as simple
* 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>
*
@ -1080,20 +1082,9 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
ChannelBuffer readBytes(int length);
/**
* Transfers this buffer's data to a newly created buffer starting at
* 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 Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #readBytes(int)} instead.
*/
@Deprecated
ChannelBuffer readBytes(ChannelBufferIndexFinder indexFinder);
/**
@ -1111,17 +1102,9 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
ChannelBuffer readSlice(int length);
/**
* Returns a new slice of this buffer's sub-region starting at the current
* {@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 Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #readSlice(int)} instead.
*/
@Deprecated
ChannelBuffer readSlice(ChannelBufferIndexFinder indexFinder);
/**
@ -1246,14 +1229,9 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
void skipBytes(int length);
/**
* Increases the current {@code readerIndex} until the specified
* {@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 Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #skipBytes(int)} instead.
*/
@Deprecated
int skipBytes(ChannelBufferIndexFinder indexFinder);
/**
@ -1483,7 +1461,7 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
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
* {@code fromIndex} (inclusive) to the specified {@code toIndex}
* (exclusive).
@ -1495,11 +1473,107 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
* this buffer.
*
* @return the absolute index where the specified {@code indexFinder}
* returned {@code true} if the {@code indexFinder} returned
* {@code true}. {@code -1} otherwise.
* returned {@code true}. {@code -1} if the {@code indexFinder}
* did not return {@code true} at all.
*/
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
* 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);
/**
* @deprecated Use {@link #toString(int, int, Charset)} instead.
* @deprecated Use {@link #bytesBefore(ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
*/
@Deprecated
String toString(
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
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
String toString(

View File

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

View File

@ -223,6 +223,57 @@ class ReplayingDecoderBuffer implements ChannelBuffer {
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() {
buffer.markReaderIndex();
}

View File

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

View File

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