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:
parent
fe73de3497
commit
5a897af28d
@ -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);
|
||||||
|
@ -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(
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user