Specialized EMPTY_BUFFER class
EmptyChannelBuffer never writes its indices, which avoids contention when the EMPTY_BUFFER singleton is used concurrently.
This commit is contained in:
parent
a30be3e73e
commit
fb9aa5fa5c
@ -100,7 +100,7 @@ public final class ChannelBuffers {
|
||||
/**
|
||||
* A buffer whose capacity is {@code 0}.
|
||||
*/
|
||||
public static final ChannelBuffer EMPTY_BUFFER = new BigEndianHeapChannelBuffer(0);
|
||||
public static final ChannelBuffer EMPTY_BUFFER = new EmptyChannelBuffer();
|
||||
|
||||
private static final char[] HEXDUMP_TABLE = new char[256 * 4];
|
||||
|
||||
|
216
src/main/java/org/jboss/netty/buffer/EmptyChannelBuffer.java
Normal file
216
src/main/java/org/jboss/netty/buffer/EmptyChannelBuffer.java
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright 2013 The Netty Project
|
||||
*
|
||||
* The Netty Project 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.jboss.netty.buffer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
|
||||
/**
|
||||
* An immutable empty buffer implementation. Typically used as a singleton via
|
||||
* {@link ChannelBuffers#EMPTY_BUFFER} and returned by {@link ChannelBuffers#buffer(int)} etc when
|
||||
* an empty buffer is requested.
|
||||
*
|
||||
* <p>Note: For backwards compatibility, this class extends {@link BigEndianHeapChannelBuffer}.
|
||||
* However, it never makes any writes to the reader and writer indices, which avoids contention
|
||||
* when the singleton instance is used concurrently.
|
||||
*/
|
||||
public class EmptyChannelBuffer extends BigEndianHeapChannelBuffer {
|
||||
|
||||
private static final byte[] BUFFER = {};
|
||||
|
||||
EmptyChannelBuffer() {
|
||||
super(BUFFER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readerIndex(int readerIndex) {
|
||||
if (readerIndex != 0) {
|
||||
throw new IndexOutOfBoundsException("Invalid readerIndex: "
|
||||
+ readerIndex + " - Maximum is 0");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writerIndex(int writerIndex) {
|
||||
if (writerIndex != 0) {
|
||||
throw new IndexOutOfBoundsException("Invalid writerIndex: "
|
||||
+ writerIndex + " - Maximum is 0");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndex(int readerIndex, int writerIndex) {
|
||||
if (writerIndex != 0 || readerIndex != 0) {
|
||||
throw new IndexOutOfBoundsException("Invalid writerIndex: "
|
||||
+ writerIndex + " - Maximum is " + readerIndex + " or "
|
||||
+ capacity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markReaderIndex() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetReaderIndex() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markWriterIndex() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetWriterIndex() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void discardReadBytes() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelBuffer readBytes(int length) {
|
||||
checkReadableBytes(length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelBuffer readSlice(int length) {
|
||||
checkReadableBytes(length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(byte[] dst, int dstIndex, int length) {
|
||||
checkReadableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(byte[] dst) {
|
||||
checkReadableBytes(dst.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(ChannelBuffer dst) {
|
||||
checkReadableBytes(dst.writableBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(ChannelBuffer dst, int length) {
|
||||
checkReadableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(ChannelBuffer dst, int dstIndex, int length) {
|
||||
checkReadableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(ByteBuffer dst) {
|
||||
checkReadableBytes(dst.remaining());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readBytes(GatheringByteChannel out, int length) throws IOException {
|
||||
checkReadableBytes(length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(OutputStream out, int length) throws IOException {
|
||||
checkReadableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipBytes(int length) {
|
||||
checkReadableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(byte[] src, int srcIndex, int length) {
|
||||
checkWritableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ChannelBuffer src, int length) {
|
||||
checkWritableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ChannelBuffer src, int srcIndex, int length) {
|
||||
checkWritableBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ByteBuffer src) {
|
||||
checkWritableBytes(src.remaining());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeBytes(InputStream in, int length) throws IOException {
|
||||
checkWritableBytes(length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeBytes(ScatteringByteChannel in, int length) throws IOException {
|
||||
checkWritableBytes(length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeZero(int length) {
|
||||
checkWritableBytes(length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link IndexOutOfBoundsException} the length is not 0.
|
||||
*/
|
||||
private void checkWritableBytes(int length) {
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
if (length > 0) {
|
||||
throw new IndexOutOfBoundsException("Writable bytes exceeded - Need "
|
||||
+ length + ", maximum is " + 0);
|
||||
} else {
|
||||
throw new IndexOutOfBoundsException("length < 0");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link IndexOutOfBoundsException} the length is not 0.
|
||||
*/
|
||||
protected void checkReadableBytes(int length) {
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
if (length > 0) {
|
||||
throw new IndexOutOfBoundsException("Not enough readable bytes - Need "
|
||||
+ length + ", maximum is " + readableBytes());
|
||||
} else {
|
||||
throw new IndexOutOfBoundsException("length < 0");
|
||||
}
|
||||
}
|
||||
}
|
@ -440,4 +440,9 @@ public class ChannelBuffersTest {
|
||||
String hexDump2 = hexDump(buffer2);
|
||||
assertEquals(hexDump, hexDump2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyBuffer() {
|
||||
assertTrue(EMPTY_BUFFER instanceof EmptyChannelBuffer);
|
||||
}
|
||||
}
|
||||
|
964
src/test/java/org/jboss/netty/buffer/EmptyChannelBufferTest.java
Normal file
964
src/test/java/org/jboss/netty/buffer/EmptyChannelBufferTest.java
Normal file
@ -0,0 +1,964 @@
|
||||
/*
|
||||
* Copyright 2012 The Netty Project
|
||||
*
|
||||
* The Netty Project 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.jboss.netty.buffer;
|
||||
|
||||
import org.jboss.netty.util.CharsetUtil;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.experimental.theories.suppliers.TestedOn;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
|
||||
import static java.nio.ByteOrder.BIG_ENDIAN;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
import static org.jboss.netty.buffer.ChannelBuffers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
public class EmptyChannelBufferTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
public static final ScatteringByteChannel SINGLE_BYTE_CHANNEL = new ScatteringByteChannel() {
|
||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||
dsts[0].put((byte) 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public long read(ByteBuffer[] dsts) throws IOException {
|
||||
dsts[0].put((byte) 0);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
dst.put((byte) 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
||||
}
|
||||
};
|
||||
private static final ScatteringByteChannel EMPTY_BYTE_CHANNEL = new ScatteringByteChannel() {
|
||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long read(ByteBuffer[] dsts) throws IOException {
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private static final GatheringByteChannel BYTE_CHANNEL_SINK = new GatheringByteChannel() {
|
||||
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||
int n = 0;
|
||||
for (ByteBuffer src : srcs) {
|
||||
n += write(src);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public long write(ByteBuffer[] srcs) throws IOException {
|
||||
return write(srcs, 0, 0);
|
||||
}
|
||||
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
int n = src.remaining();
|
||||
src.get(new byte[src.remaining()]);
|
||||
return n;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public static final byte[] SINGLE_BYTE = new byte[]{0};
|
||||
|
||||
public static final ChannelBufferIndexFinder POSITIVE_INDEX_FINDER = new ChannelBufferIndexFinder() {
|
||||
public boolean find(ChannelBuffer buffer, int guessedIndex) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public static final ChannelBuffer UNWRITTEN_BUFFER = buffer(1);
|
||||
|
||||
final ChannelBuffer b = EMPTY_BUFFER;
|
||||
|
||||
@Test
|
||||
public void testDiscardReadBytes() {
|
||||
b.discardReadBytes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() {
|
||||
b.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteBytes() throws IOException {
|
||||
b.writeBytes(new byte[]{});
|
||||
b.writeBytes(new byte[]{}, 0, 0);
|
||||
b.writeBytes(ByteBuffer.wrap(new byte[]{}));
|
||||
b.writeBytes(buffer(0));
|
||||
b.writeBytes(buffer(0), 0);
|
||||
b.writeBytes(buffer(0), 0, 0);
|
||||
b.writeBytes(new ChannelBufferInputStream(buffer(0)), 0);
|
||||
b.writeBytes(EMPTY_BYTE_CHANNEL, 0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testWriteBytesIndexOutOfBounds(@TestedOn(ints = {-1, 1}) int length) throws IOException {
|
||||
|
||||
try {
|
||||
b.writeBytes(SINGLE_BYTE);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(SINGLE_BYTE, 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(ByteBuffer.wrap(SINGLE_BYTE));
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(wrappedBuffer(SINGLE_BYTE));
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(wrappedBuffer(SINGLE_BYTE), length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(wrappedBuffer(SINGLE_BYTE), 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(new ChannelBufferInputStream(wrappedBuffer(SINGLE_BYTE)), length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(SINGLE_BYTE_CHANNEL, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeBytes(SINGLE_BYTE, 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteZero() {
|
||||
b.writeZero(0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testWriteZeroOutOfBounds(@TestedOn(ints = {-1, 1}) int length) {
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.writeZero(length);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testSetZero(@TestedOn(ints = {-1, 1}) int offset) {
|
||||
b.setZero(0, 0);
|
||||
b.setZero(1, 0);
|
||||
b.setZero(-1, 0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testSetZeroOutOfBounds(@TestedOn(ints = {-1, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 1}) int length) {
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.setZero(offset, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetBytes() {
|
||||
b.setBytes(0, wrappedBuffer(new byte[]{}), 0);
|
||||
b.setBytes(0, wrappedBuffer(new byte[]{}), 0, 0);
|
||||
b.setBytes(0, ByteBuffer.wrap(new byte[]{}));
|
||||
b.setBytes(0, buffer(0));
|
||||
b.setBytes(0, buffer(0));
|
||||
b.setBytes(0, buffer(0), 0);
|
||||
b.setBytes(0, buffer(0), 0, 0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testSetBytesIndexOutOfBounds(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int length) {
|
||||
|
||||
assumeThat(asList(offset, length), not(asList(0, 0)));
|
||||
|
||||
try {
|
||||
b.setBytes(offset, SINGLE_BYTE);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setBytes(offset, SINGLE_BYTE, 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setBytes(offset, wrappedBuffer(SINGLE_BYTE), length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setBytes(offset, wrappedBuffer(SINGLE_BYTE), 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setBytes(offset, ByteBuffer.wrap(SINGLE_BYTE));
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testSetPrimitives(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int value) {
|
||||
try {
|
||||
b.setByte(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setChar(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setShort(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setMedium(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setInt(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setLong(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setFloat(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setDouble(offset, value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testGetPrimitives(@TestedOn(ints = {-1, 0, 1}) int offset) {
|
||||
try {
|
||||
b.getByte(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getChar(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getShort(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getMedium(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getInt(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getLong(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getUnsignedByte(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getUnsignedShort(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getUnsignedMedium(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getUnsignedInt(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getDouble(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getFloat(offset);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopy() {
|
||||
assertEquals(EMPTY_BUFFER, b.copy());
|
||||
assertEquals(EMPTY_BUFFER, b.copy(0, 0));
|
||||
}
|
||||
|
||||
@Theory
|
||||
void testCopyOutOfBounds(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int length) {
|
||||
assumeThat(asList(offset, length), not(asList(0, 0)));
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.copy(offset, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadPrimitives() {
|
||||
try {
|
||||
b.readByte();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readChar();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readDouble();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readFloat();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readInt();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readLong();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readMedium();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readShort();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readUnsignedByte();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readUnsignedInt();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readUnsignedMedium();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readUnsignedShort();
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testWritePrimitives(@TestedOn(ints = {-1, 0, 1}) int value) {
|
||||
try {
|
||||
b.writeByte(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeChar(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeDouble(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeFloat(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeInt(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeLong(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeMedium(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.writeShort(value);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadBytes() throws IOException {
|
||||
assertEquals(EMPTY_BUFFER, b.readBytes(0));
|
||||
b.readBytes(new byte[]{});
|
||||
b.readBytes(new byte[]{}, 0, 0);
|
||||
b.readBytes(ByteBuffer.allocate(0));
|
||||
b.readBytes(buffer(0));
|
||||
b.readBytes(buffer(0), 0);
|
||||
b.readBytes(buffer(0), 0, 0);
|
||||
b.readBytes(BYTE_CHANNEL_SINK, 0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testReadBytesOutOfBounds(@TestedOn(ints = {-1, 1}) int length) throws IOException {
|
||||
|
||||
try {
|
||||
b.readBytes(length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readBytes(new byte[1]);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readBytes(new byte[1], 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readBytes(ByteBuffer.allocate(1));
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readBytes(buffer(1));
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readBytes(buffer(1), length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readBytes(buffer(1), 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readBytes(BYTE_CHANNEL_SINK, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexes() {
|
||||
assertEquals(0, b.readerIndex());
|
||||
assertEquals(0, b.writerIndex());
|
||||
assertEquals(0, b.readableBytes());
|
||||
assertEquals(0, b.writableBytes());
|
||||
assertFalse(b.readable());
|
||||
assertFalse(b.writable());
|
||||
|
||||
b.markReaderIndex();
|
||||
b.markWriterIndex();
|
||||
b.resetReaderIndex();
|
||||
b.resetWriterIndex();
|
||||
|
||||
b.writerIndex(0);
|
||||
b.readerIndex(0);
|
||||
|
||||
b.setIndex(0, 0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIndexesOutOfBounds(@TestedOn(ints = {-1, 0, 1}) int writer,
|
||||
@TestedOn(ints = {-1, 0, 1}) int reader) {
|
||||
|
||||
assumeThat(asList(writer, reader), not(asList(0, 0)));
|
||||
|
||||
try {
|
||||
b.writerIndex(writer);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.readerIndex(reader);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.setIndex(reader, writer);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIndexOf(@TestedOn(ints = {-1, 0, 1}) int from,
|
||||
@TestedOn(ints = {-1, 0, 1}) int to,
|
||||
@TestedOn(ints = {-1, 0, 1}) int value) {
|
||||
assertEquals(-1, b.indexOf(from, to, (byte) value));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
assertTrue(b.equals(EMPTY_BUFFER));
|
||||
assertTrue(b.equals(ChannelBuffers.buffer(1)));
|
||||
assertFalse(b.equals(wrappedBuffer(SINGLE_BYTE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactory() {
|
||||
assertEquals(HeapChannelBufferFactory.getInstance(BIG_ENDIAN), b.factory());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnsureWritableBytes() {
|
||||
b.ensureWritableBytes(0);
|
||||
|
||||
try {
|
||||
b.ensureWritableBytes(1);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSlice() {
|
||||
assertEquals(EMPTY_BUFFER, b.slice());
|
||||
assertEquals(EMPTY_BUFFER, b.slice(0, 0));
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testSliceOutOfBounds(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int length) {
|
||||
assumeThat(asList(offset, length), not(asList(0, 0)));
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.slice(offset, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadSlice() {
|
||||
assertEquals(EMPTY_BUFFER, b.readSlice(0));
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testReadSliceOutOfBounds(@TestedOn(ints = {-1, 1}) int length) {
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.readSlice(length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicate() {
|
||||
assertEquals(EMPTY_BUFFER, b.duplicate());
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testBytesBefore(@TestedOn(ints = {-1, 0, 1}) int value) {
|
||||
assertEquals(-1, b.bytesBefore((byte) value));
|
||||
assertEquals(-1, b.bytesBefore(POSITIVE_INDEX_FINDER));
|
||||
assertEquals(-1, b.bytesBefore(0, (byte) value));
|
||||
assertEquals(-1, b.bytesBefore(0, (byte) value));
|
||||
assertEquals(-1, b.bytesBefore(0, 0, (byte) value));
|
||||
assertEquals(-1, b.bytesBefore(0, 0, POSITIVE_INDEX_FINDER));
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testBytesBeforeOutOfBounds1(@TestedOn(ints = {-1, 1}) int offset) {
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.bytesBefore(offset, POSITIVE_INDEX_FINDER);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testBytesBeforeOutOfBounds2(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int length) {
|
||||
assumeThat(asList(offset, length), not(asList(0, 0)));
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.bytesBefore(offset, length, POSITIVE_INDEX_FINDER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrder() {
|
||||
assertEquals(ChannelBuffers.BIG_ENDIAN, b.order());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArray() {
|
||||
assertEquals(0, b.array().length);
|
||||
assertEquals(0, b.arrayOffset());
|
||||
assertTrue(b.hasArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCapacity() {
|
||||
assertEquals(0, b.capacity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareTo() {
|
||||
assertEquals(-1, b.compareTo(wrappedBuffer(SINGLE_BYTE)));
|
||||
assertEquals(0, b.compareTo(buffer(0)));
|
||||
assertEquals(0, b.compareTo(new BigEndianHeapChannelBuffer(0)));
|
||||
assertEquals(0, b.compareTo(new BigEndianHeapChannelBuffer(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsDirect() {
|
||||
assertFalse(b.isDirect());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToByteBuffer() {
|
||||
assertEquals(ByteBuffer.allocate(0), b.toByteBuffer());
|
||||
assertEquals(ByteBuffer.allocate(0), b.toByteBuffer(0, 0));
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testToByteBufferOutOfBounds(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int length) {
|
||||
assumeThat(asList(offset, length), not(asList(0, 0)));
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.toByteBuffer(offset, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToByteBuffers() {
|
||||
assertArrayEquals(new ByteBuffer[]{ByteBuffer.allocate(0)}, b.toByteBuffers());
|
||||
assertArrayEquals(new ByteBuffer[]{ByteBuffer.allocate(0)}, b.toByteBuffers(0, 0));
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testToByteBuffersOutOfBounds(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int length) {
|
||||
assumeThat(asList(offset, length), not(asList(0, 0)));
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.toByteBuffers(offset, length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBytes() throws IOException {
|
||||
b.getBytes(0, new byte[0]);
|
||||
b.getBytes(0, new byte[0], 0, 0);
|
||||
b.getBytes(0, ByteBuffer.allocate(0));
|
||||
b.getBytes(0, buffer(0));
|
||||
b.getBytes(0, buffer(0), 0);
|
||||
b.getBytes(0, buffer(0), 0, 0);
|
||||
b.getBytes(0, BYTE_CHANNEL_SINK, 0);
|
||||
b.getBytes(0, new ChannelBufferOutputStream(buffer(0)), 0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testGetBytesOutOfBounds(@TestedOn(ints = {-1, 0, 1}) int offset,
|
||||
@TestedOn(ints = {-1, 0, 1}) int length) throws IOException {
|
||||
assumeThat(asList(offset, length), not(asList(0, 0)));
|
||||
|
||||
try {
|
||||
b.getBytes(offset, new byte[1]);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getBytes(offset, new byte[1], 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getBytes(offset, ByteBuffer.allocate(1));
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getBytes(offset, buffer(1));
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getBytes(offset, buffer(1), 0);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getBytes(offset, buffer(1), 0, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getBytes(offset, BYTE_CHANNEL_SINK, length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
try {
|
||||
b.getBytes(offset, new ChannelBufferOutputStream(buffer(length)), length);
|
||||
fail();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipBytes() {
|
||||
b.skipBytes(0);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testSkipBytesOutOfBounds(@TestedOn(ints = {-1, 1}) int length) {
|
||||
thrown.expect(IndexOutOfBoundsException.class);
|
||||
b.skipBytes(length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHashCode() {
|
||||
assertEquals(ChannelBuffers.hashCode(UNWRITTEN_BUFFER), b.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
b.toString();
|
||||
assertEquals("", b.toString(CharsetUtil.UTF_8));
|
||||
assertEquals("", b.toString(0, 0, CharsetUtil.UTF_8));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user