diff --git a/buffer/src/main/java/io/netty/buffer/Buf.java b/buffer/src/main/java/io/netty/buffer/Buf.java index 699153d845..93d770a78b 100644 --- a/buffer/src/main/java/io/netty/buffer/Buf.java +++ b/buffer/src/main/java/io/netty/buffer/Buf.java @@ -15,6 +15,9 @@ */ package io.netty.buffer; +/** + * A buffer to operate on + */ public interface Buf { /** * The BufType which will be handled by the Buf implementation diff --git a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java index bb7576aba3..efc75431be 100644 --- a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java +++ b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java @@ -26,6 +26,9 @@ import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; +/** + * Utility class for operate on a {@link ByteBuf} + */ public final class ByteBufUtil { private static final char[] HEXDUMP_TABLE = new char[256 * 4]; diff --git a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java index ed51559581..d570761ce8 100644 --- a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java @@ -20,30 +20,171 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.List; +/** + * A {@link ByteBuf} which is composed out of other {@link ByteBuf}s. + */ public interface CompositeByteBuf extends ByteBuf, Iterable { + /** + * Add the given {@link ByteBuf}. + * + * @param buffer the {@link ByteBuf} to add + * @return self this instance + */ CompositeByteBuf addComponent(ByteBuf buffer); + + /** + * Add the given {@link ByteBuf} on the specific index. + * + * @param cIndex + * the index on which the {@link ByteBuf} will be added + * @param buffer + * the {@link ByteBuf} to add + * @return self + * this instance + * @thows {@link IndexOutOfBoundsException} + * if the index is invalid + */ CompositeByteBuf addComponent(int cIndex, ByteBuf buffer); + /** + * Add the given {@link ByteBuf}s. + * + * @param buffers the {@link ByteBuf}s to add + * @return self this instance + */ CompositeByteBuf addComponents(ByteBuf... buffers); + + /** + * Add the given {@link ByteBuf}s. + * + * @param buffers the {@link ByteBuf}s to add + * @return self this instance + */ CompositeByteBuf addComponents(Iterable buffers); + + /** + * Add the given {@link ByteBuf}s on the specific index + * + * @param cIndex + * the index on which the {@link ByteBuf} will be added. + * @param buffers + * the {@link ByteBuf}s to add + * @return self + * this instance + * @thows {@link IndexOutOfBoundsException} + * if the index is invalid + * + */ CompositeByteBuf addComponents(int cIndex, ByteBuf... buffers); + + /** + * Add the given {@link ByteBuf}s on the specific index + * + * @param cIndex + * the index on which the {@link ByteBuf} will be added. + * @param buffers + * the {@link ByteBuf}s to add + * @return self + * this instance + * @thows {@link IndexOutOfBoundsException} + * if the index is invalid + */ CompositeByteBuf addComponents(int cIndex, Iterable buffers); + /** + * Remove the {@link ByteBuf} from the given index. + * + * @param cIndex + * the index on from which the {@link ByteBuf} will be remove + * @return self + * this instance + * @thows {@link IndexOutOfBoundsException} + * if the index is invalid + */ CompositeByteBuf removeComponent(int cIndex); + + /** + * Remove the number of {@link ByteBuf}s starting from the given index. + * + * @param cIndex + * the index on which the {@link ByteBuf}s will be started to removed + * @param numComponents + * the number of components to remove + * @return self + * this instance + * @thows {@link IndexOutOfBoundsException} + * if the index is invalid + */ CompositeByteBuf removeComponents(int cIndex, int numComponents); + /** + * Return the current number of {@link ByteBuf}'s that are composed in this instance + */ int numComponents(); + + /** + * Return the max number of {@link ByteBuf}'s that are composed in this instance + */ int maxNumComponents(); + /** + * Return the {@link ByteBuf} on the specified index + * + * @param cIndex + * the index for which the {@link ByteBuf} should be returned + * @return buf + * the {@link ByteBuf} on the specified index + * @thows {@link IndexOutOfBoundsException} + * if the index is invalid + */ ByteBuf component(int cIndex); + + /** + * Return the {@link ByteBuf} on the specified index + * + * @param offset + * the offset for which the {@link ByteBuf} should be returned + * @return buf + * the {@link ByteBuf} on the specified index + * @thows {@link IndexOutOfBoundsException} + * if the offset is invalid + */ ByteBuf componentAtOffset(int offset); + /** + * Discard all {@link ByteBuf}s which are read. + * + * @return self this instance + */ CompositeByteBuf discardReadComponents(); + + /** + * Consolidate the composed {@link ByteBuf}s + * + * @return self this instance + */ CompositeByteBuf consolidate(); + + /** + * Consolidate the composed {@link ByteBuf}s + * + * @param cIndex + * the index on which to start to compose + * @param numComponents + * the number of components to compose + * @return self + * this instance + * @thows {@link IndexOutOfBoundsException} + * if the offset is invalid + */ CompositeByteBuf consolidate(int cIndex, int numComponents); + /** + * Return the index for the given offset + */ int toComponentIndex(int offset); + int toByteIndex(int cIndex); /** diff --git a/buffer/src/main/java/io/netty/buffer/DefaultMessageBuf.java b/buffer/src/main/java/io/netty/buffer/DefaultMessageBuf.java index 744d876d42..98135173b7 100644 --- a/buffer/src/main/java/io/netty/buffer/DefaultMessageBuf.java +++ b/buffer/src/main/java/io/netty/buffer/DefaultMessageBuf.java @@ -19,6 +19,10 @@ import java.util.ArrayDeque; import java.util.Collection; import java.util.Iterator; +/** + * Default {@link MessageBuf} implementation + * + */ final class DefaultMessageBuf extends ArrayDeque implements MessageBuf { private static final long serialVersionUID = 1229808623624907552L; diff --git a/buffer/src/main/java/io/netty/buffer/MessageBuf.java b/buffer/src/main/java/io/netty/buffer/MessageBuf.java index 08b020b936..517a01841f 100644 --- a/buffer/src/main/java/io/netty/buffer/MessageBuf.java +++ b/buffer/src/main/java/io/netty/buffer/MessageBuf.java @@ -19,11 +19,26 @@ import java.util.Collection; import java.util.Queue; /** - * Buf which operates on messages + * Buf which operates on messages. * - * @param + * @param the type of the messages that are hold by this {@link MessageBuf} */ public interface MessageBuf extends Buf, Queue { + + /** + * Drain the content of te {@link MessageBuf} to the given {@link Collection}. + * + * @param c the {@link Collection} to drain the content to + * @return number the number of objects which was transfered + */ int drainTo(Collection c); + + /** + * Drain the content of te {@link MessageBuf} to the given {@link Collection}. + * + * @param c the {@link Collection} to drain the content to + * @param maxElements the max number of elements to drain + * @return number the number of objects which was transfered + */ int drainTo(Collection c, int maxElements); } diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToByteCodec.java b/codec/src/main/java/io/netty/handler/codec/ByteToByteCodec.java index da99943e70..0453ca3b3f 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToByteCodec.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToByteCodec.java @@ -23,6 +23,36 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundByteHandler; import io.netty.channel.ChannelOutboundByteHandler; +/** + * A Codec for on-the-fly encoding/decoding of bytes. + * + * This can be though of an combination of {@link ByteToByteDecoder} and {@link ByteToByteEncoder}. + * + * Here is an example of a {@link ByteToByteCodec} which just square {@link Integer} read from a {@link ByteBuf}. + *
+ *     public class SquareCodec extends {@link ByteToByteCodec} {
+ *         {@code @Override}
+ *         public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, {@link ByteBuf} out)
+ *                 throws {@link Exception} {
+ *             if (in.readableBytes() < 4) {
+ *                 return;
+ *             }
+ *             int value = in.readInt();
+ *             out.writeInt(value * value);
+ *         }
+ *
+ *         {@code @Overrride}
+ *         public void encode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, {@link ByteBuf} out)
+ *                 throws {@link Exception} {
+ *             if (in.readableBytes() < 4) {
+ *                 return;
+ *             }
+ *             int value = in.readInt();
+ *             out.writeInt(value / value);
+ *         }
+ *     }
+ * 
+ */ public abstract class ByteToByteCodec extends ChannelHandlerAdapter implements ChannelInboundByteHandler, ChannelOutboundByteHandler { @@ -76,10 +106,16 @@ public abstract class ByteToByteCodec encoder.freeOutboundBuffer(ctx, buf); } + /** + * @see {@link ByteToByteEncoder#encode(ChannelHandlerContext, ByteBuf, ByteBuf)} + */ public abstract void encode( ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception; + /** + * @see {@link ByteToByteDecoder#decode(ChannelHandlerContext, ByteBuf, ByteBuf)} + */ public abstract void decode( ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception; diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToByteDecoder.java b/codec/src/main/java/io/netty/handler/codec/ByteToByteDecoder.java index d8b3cdec67..38a12a7d45 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToByteDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToByteDecoder.java @@ -19,6 +19,29 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundByteHandlerAdapter; +/** + * {@link ChannelInboundByteHandlerAdapter} which decodes bytes in a stream-like fashion from one {@link ByteBuf} to an + * other. + * + * This kind of decoder is often useful for doing on-the-fly processiing like i.e. compression. + * + * But you can also do other things with it. For example here is an implementation which reads {@link Integer}s from + * the input {@link ByteBuf} and square them before write them to the output {@link ByteBuf}. + * + *
+ *     public class SquareDecoder extends {@link ByteToByteDecoder} {
+ *         {@code @Override}
+ *         public void decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, {@link ByteBuf} out)
+ *                 throws {@link Exception} {
+ *             if (in.readableBytes() < 4) {
+ *                 return;
+ *             }
+ *             int value = in.readInt();
+ *             out.writeInt(value * value);
+ *         }
+ *     }
+ * 
+ */ public abstract class ByteToByteDecoder extends ChannelInboundByteHandlerAdapter { @Override @@ -52,6 +75,9 @@ public abstract class ByteToByteDecoder extends ChannelInboundByteHandlerAdapter ctx.fireChannelInactive(); } + /** + * Call the {@link #decode(ChannelHandlerContext, ByteBuf, ByteBuf)} method until it is done. + */ private void callDecode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) { int oldOutSize = out.readableBytes(); while (in.readable()) { @@ -76,8 +102,24 @@ public abstract class ByteToByteDecoder extends ChannelInboundByteHandlerAdapter } } + /** + * Decode the from one {@link ByteBuf} to an other. This method will be called till either the input + * {@link ByteBuf} has nothing to read anymore or till nothing was read from the input {@link ByteBuf}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToByteDecoder} belongs to + * @param in the {@link ByteBuf} from which to read data + * @param out the {@link ByteBuf} to which the decoded data will be written + * @throws Exception is thrown if an error accour + */ public abstract void decode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception; + /** + * Is called one last time when the {@link ChannelHandlerContext} goes in-active. Which means the + * {@link #channelInactive(ChannelHandlerContext)} was triggered. + * + * By default this will just call {@link #decode(ChannelHandlerContext, ByteBuf, ByteBuf)} but sub-classes may + * override this for some special cleanup operation. + */ public void decodeLast(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception { decode(ctx, in, out); } diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToByteEncoder.java b/codec/src/main/java/io/netty/handler/codec/ByteToByteEncoder.java index 360e5b03b8..a98f547e54 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToByteEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToByteEncoder.java @@ -20,6 +20,29 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundByteHandlerAdapter; +/** + * {@link ChannelOutboundByteHandlerAdapter} which encodes bytes in a stream-like fashion from one {@link ByteBuf} to an + * other. + * + * This kind of decoder is often useful for doing on-the-fly processing like i.e. compression. + * + * But you can also do other things with it. For example here is an implementation which reads {@link Integer}s from + * the input {@link ByteBuf} and square them before write them to the output {@link ByteBuf}. + * + *
+ *     public class SquareEncoder extends {@link ByteToByteEncoder} {
+ *         {@code @Override}
+ *         public void encode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in, {@link ByteBuf} out)
+ *                 throws {@link Exception} {
+ *             if (in.readableBytes() < 4) {
+ *                 return;
+ *             }
+ *             int value = in.readInt();
+ *             out.writeInt(value * value);
+ *         }
+ *     }
+ * 
+ */ public abstract class ByteToByteEncoder extends ChannelOutboundByteHandlerAdapter { @Override @@ -47,5 +70,14 @@ public abstract class ByteToByteEncoder extends ChannelOutboundByteHandlerAdapte ctx.flush(future); } + /** + * Encodes the from one {@link ByteBuf} to an other. This method will be called till either the input + * {@link ByteBuf} has nothing to read anymore or till nothing was read from the input {@link ByteBuf}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToByteDecoder} belongs to + * @param in the {@link ByteBuf} from which to read data + * @param out the {@link ByteBuf} to which the decoded data will be written + * @throws Exception is thrown if an error accour + */ public abstract void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception; } diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java index 5272272ffa..fdd2b70439 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java @@ -22,6 +22,23 @@ import io.netty.channel.ChannelInboundByteHandler; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelPipeline; +/** + * {@link ChannelInboundByteHandler} which decodes bytes in a stream-like fashion from one {@link ByteBuf} to an other + * Message type. + * + * For example here is an implementation which reads all readable bytes from + * the input {@link ByteBuf} and create a new {@link ByteBuf}. + * + *
+ *     public class SquareDecoder extends {@link ByteToMessageDecoder}<{@link ByteBuf}> {
+ *         {@code @Override}
+ *         public {@link ByteBuf} decode({@link ChannelHandlerContext} ctx, {@link ByteBuf} in)
+ *                 throws {@link Exception} {
+ *             return in.readBytes(in.readableBytes());
+ *         }
+ *     }
+ * 
+ */ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter implements ChannelInboundByteHandler { @@ -138,8 +155,26 @@ public abstract class ByteToMessageDecoder } } + /** + * Decode the from one {@link ByteBuf} to an other. This method will be called till either the input + * {@link ByteBuf} has nothing to read anymore, till nothing was read from the input {@link ByteBuf} or till + * this method returns {@code null}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToByteDecoder} belongs to + * @param in the {@link ByteBuf} from which to read data + * @return message the message to which the content of the {@link ByteBuf} was decoded, or {@code null} if + * there was not enough data left in the {@link ByteBuf} to decode. + * @throws Exception is thrown if an error accour + */ public abstract O decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception; + /** + * Is called one last time when the {@link ChannelHandlerContext} goes in-active. Which means the + * {@link #channelInactive(ChannelHandlerContext)} was triggered. + * + * By default this will just call {@link #decode(ChannelHandlerContext, ByteBuf)} but sub-classes may + * override this for some special cleanup operation. + */ public O decodeLast(ChannelHandlerContext ctx, ByteBuf in) throws Exception { return decode(ctx, in); } diff --git a/codec/src/main/java/io/netty/handler/codec/CorruptedFrameException.java b/codec/src/main/java/io/netty/handler/codec/CorruptedFrameException.java index 20296fd1e0..2d7779f57e 100644 --- a/codec/src/main/java/io/netty/handler/codec/CorruptedFrameException.java +++ b/codec/src/main/java/io/netty/handler/codec/CorruptedFrameException.java @@ -16,7 +16,7 @@ package io.netty.handler.codec; /** - * An {@link Exception} which is thrown when the received frame data could not be decoded by + * An {@link DecoderException} which is thrown when the received frame data could not be decoded by * an inbound handler. * * @apiviz.exclude diff --git a/codec/src/main/java/io/netty/handler/codec/DecoderException.java b/codec/src/main/java/io/netty/handler/codec/DecoderException.java index 92bb513bb3..94298a4715 100644 --- a/codec/src/main/java/io/netty/handler/codec/DecoderException.java +++ b/codec/src/main/java/io/netty/handler/codec/DecoderException.java @@ -16,7 +16,7 @@ package io.netty.handler.codec; /** - * An {@link Exception} which is thrown by an encoder. + * An {@link CodecException} which is thrown by a dencoder. * * @apiviz.exclude */ diff --git a/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java index 9609b29fc4..0e32e6d412 100644 --- a/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/DelimiterBasedFrameDecoder.java @@ -39,7 +39,7 @@ import io.netty.channel.ChannelHandlerContext; * | ABC\nDEF\r\n | * +--------------+ * - * a {@link DelimiterBasedFrameDecoder}{@code (}{@link Delimiters#lineDelimiter() Delimiters.lineDelimiter()}{@code )} + * a {@link DelimiterBasedFrameDecoder}({@link Delimiters#lineDelimiter() Delimiters.lineDelimiter()}) * will choose {@code '\n'} as the first delimiter and produce two frames: *
  * +-----+-----+
diff --git a/codec/src/main/java/io/netty/handler/codec/EncoderException.java b/codec/src/main/java/io/netty/handler/codec/EncoderException.java
index 08460d02ac..83ce03e623 100644
--- a/codec/src/main/java/io/netty/handler/codec/EncoderException.java
+++ b/codec/src/main/java/io/netty/handler/codec/EncoderException.java
@@ -16,7 +16,7 @@
 package io.netty.handler.codec;
 
 /**
- * An {@link Exception} which is thrown by an encoder.
+ * An {@link CodecException} which is thrown by an encoder.
  *
  * @apiviz.exclude
  */
diff --git a/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java b/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java
index 4e1f4bd170..90cc0cdf52 100644
--- a/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java
+++ b/codec/src/main/java/io/netty/handler/codec/LengthFieldBasedFrameDecoder.java
@@ -411,14 +411,10 @@ public class LengthFieldBasedFrameDecoder extends ByteToMessageDecoder {
     }
 
     /**
-     * Extract the sub-region of the specified buffer. This method is called by
-     * {@link #decode(ChannelInboundHandlerContext, ByteBuf)} for each
-     * frame.  The default implementation returns a copy of the sub-region.
-     * For example, you could override this method to use an alternative
-     * {@link ByteBufFactory}.
+     * Extract the sub-region of the specified buffer.
      * 

* If you are sure that the frame and its content are not accessed after - * the current {@link #decode(ChannelInboundHandlerContext, ByteBuf)} + * the current {@link #decode(ChannelHandlerContext, ByteBuf)} * call returns, you can even avoid memory copy by returning the sliced * sub-region (i.e. return buffer.slice(index, length)). * It's often useful when you convert the extracted frame into an object. diff --git a/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java b/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java index 83cceab485..a7c5d050b3 100644 --- a/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java +++ b/codec/src/main/java/io/netty/handler/codec/LengthFieldPrepender.java @@ -19,13 +19,10 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; -import java.nio.ByteOrder; /** * An encoder that prepends the length of the message. The length value is - * prepended as a binary form. It is encoded in either big endian or little - * endian depending on the default {@link ByteOrder} of the current - * {@link ByteBufFactory}. + * prepended as a binary form. *

* For example, {@link LengthFieldPrepender}(2) will encode the * following 12-bytes string: diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java index 13e1096ada..9f7035a09c 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToByteEncoder.java @@ -22,6 +22,24 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundMessageHandlerAdapter; import io.netty.channel.ChannelHandlerUtil; + +/** + * {@link ChannelOutboundMessageHandlerAdapter} which encodes message in a stream-like fashion from one message to an + * {@link ByteBuf}. + * + * + * Example implementation which encodes {@link Integer}s to a {@link ByteBuf}. + * + *

+ *     public class IntegerEncoder extends {@link MessageToByteEncoder}<{@link Integer}> {
+ *         {@code @Override}
+ *         public void encode({@link ChannelHandlerContext} ctx, {@link Integer} msg, {@link ByteBuf} out)
+ *                 throws {@link Exception} {
+ *             out.writeInt(msg);
+ *         }
+ *     }
+ * 
+ */ public abstract class MessageToByteEncoder extends ChannelOutboundMessageHandlerAdapter { private final Class[] acceptedMsgTypes; @@ -71,5 +89,14 @@ public abstract class MessageToByteEncoder extends ChannelOutboundMessageHand return ChannelHandlerUtil.acceptMessage(acceptedMsgTypes, msg); } + /** + * Encode a message into a {@link ByteBuf}. This method will be called till the {@link MessageBuf} has + * nothing left. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToByteEncoder} belongs to + * @param msg the message to encode + * @param out the {@link ByteBuf} into which the encoded message will be written + * @throws Exception is thrown if an error accour + */ public abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception; } diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToMessageCodec.java b/codec/src/main/java/io/netty/handler/codec/MessageToMessageCodec.java index d49bfc1c9b..770a7b9875 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToMessageCodec.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToMessageCodec.java @@ -24,6 +24,30 @@ import io.netty.channel.ChannelHandlerUtil; import io.netty.channel.ChannelInboundMessageHandler; import io.netty.channel.ChannelOutboundMessageHandler; +/** + * A Codec for on-the-fly encoding/decoding of message. + * + * This can be though of an combination of {@link MessageToMessageDecoder} and {@link MessageToMessageEncoder}. + * + * Here is an example of a {@link MessageToMessageCodec} which just decode from {@link Integer} to {@link Long} + * and encode from {@link Long} to {@link Integer}. + *
+ *     public class NumberCodec extends
+ *             {@link MessageToMessageCodec}<{@link Integer}, {@link Long}, {@link Long}, {@link Integer}> {
+ *         {@code @Override}
+ *         public {@link Long} decode({@link ChannelHandlerContext} ctx, {@link Integer} msg)
+ *                 throws {@link Exception} {
+ *             return msg.longValue();
+ *         }
+ *
+ *         {@code @Overrride}
+ *         public {@link Integer} encode({@link ChannelHandlerContext} ctx, {@link Long} msg)
+ *                 throws {@link Exception} {
+ *             return msg.intValue();
+ *         }
+ *     }
+ * 
+ */ public abstract class MessageToMessageCodec extends ChannelHandlerAdapter implements ChannelInboundMessageHandler, diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java index 600e6dc426..bd546956a8 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToMessageDecoder.java @@ -21,12 +21,38 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerUtil; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundMessageHandler; +import io.netty.channel.ChannelPipeline; +/** + * {@link ChannelInboundMessageHandler} which decodes from one message to an other message + * + * For example here is an implementation which decodes a {@link String} to an {@link Integer} which represent + * the length of the {@link String}. + * + *
+ *     public class StringToIntegerDecoder extends
+ *             {@link MessageToMessageDecoder}<{@link String},{@link Integer}> {
+ *         public StringToIntegerDecoder() {
+ *             super(String.class);
+ *         }
+ *
+ *         {@code @Override}
+ *         public {@link Integer} decode({@link ChannelHandlerContext} ctx, {@link String} message)
+ *                 throws {@link Exception} {
+ *             return message.length());
+ *         }
+ *     }
+ * 
+ */ public abstract class MessageToMessageDecoder extends ChannelInboundHandlerAdapter implements ChannelInboundMessageHandler { private final Class[] acceptedMsgTypes; + /** + * The types which will be accepted by the decoder. If a received message is an other type it will be just forwared + * to the next {@link ChannelInboundMessageHandler} in the {@link ChannelPipeline} + */ protected MessageToMessageDecoder(Class... acceptedMsgTypes) { this.acceptedMsgTypes = ChannelHandlerUtil.acceptedMessageTypes(acceptedMsgTypes); } @@ -80,12 +106,20 @@ public abstract class MessageToMessageDecoder /** * Returns {@code true} if and only if the specified message can be decoded by this decoder. - * - * @param msg the message */ public boolean isDecodable(Object msg) throws Exception { return ChannelHandlerUtil.acceptMessage(acceptedMsgTypes, msg); } + /** + * Decode from one message to an other. This method will be called till either the {@link MessageBuf} has + * nothing left or till this method returns {@code null}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageDecoder} belongs to + * @param msg the message to decode to an other one + * @return message the decoded message or {@code null} if more messages are needed be cause the implementation + * needs to do some kind of aggragation + * @throws Exception is thrown if an error accour + */ public abstract O decode(ChannelHandlerContext ctx, I msg) throws Exception; } diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java index f6715ede59..c1aaf6dafa 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java @@ -18,13 +18,39 @@ package io.netty.handler.codec; import io.netty.buffer.MessageBuf; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundMessageHandler; import io.netty.channel.ChannelOutboundMessageHandlerAdapter; import io.netty.channel.ChannelHandlerUtil; +import io.netty.channel.ChannelPipeline; +/** + * {@link ChannelOutboundMessageHandlerAdapter} which encodes from one message to an other message + * + * For example here is an implementation which decodes an {@link Integer} to an {@link String}. + * + *
+ *     public class IntegerToStringEncoder extends
+ *             {@link MessageToMessageEncoder}<{@link Integer},{@link String}> {
+ *         public StringToIntegerDecoder() {
+ *             super(String.class);
+ *         }
+ *
+ *         {@code @Override}
+ *         public {@link String} encode({@link ChannelHandlerContext} ctx, {@link Integer} message)
+ *                 throws {@link Exception} {
+ *             return message.toString();
+ *         }
+ *     }
+ * 
+ */ public abstract class MessageToMessageEncoder extends ChannelOutboundMessageHandlerAdapter { private final Class[] acceptedMsgTypes; + /** + * The types which will be accepted by the decoder. If a received message is an other type it will be just forwared + * to the next {@link ChannelOutboundMessageHandler} in the {@link ChannelPipeline} + */ protected MessageToMessageEncoder(Class... acceptedMsgTypes) { this.acceptedMsgTypes = ChannelHandlerUtil.acceptedMessageTypes(acceptedMsgTypes); } @@ -75,5 +101,15 @@ public abstract class MessageToMessageEncoder extends ChannelOutboundMessa return ChannelHandlerUtil.acceptMessage(acceptedMsgTypes, msg); } + /** + * Encode from one message to an other. This method will be called till either the {@link MessageBuf} has nothing + * left or till this method returns {@code null}. + * + * @param ctx the {@link ChannelHandlerContext} which this {@link MessageToMessageEncoder} belongs to + * @param msg the message to encode to an other one + * @return message the encoded message or {@code null} if more messages are needed be cause the implementation + * needs to do some kind of aggragation + * @throws Exception is thrown if an error accour + */ public abstract O encode(ChannelHandlerContext ctx, I msg) throws Exception; } diff --git a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java index bed8efb37c..66699b1cc7 100644 --- a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoder.java @@ -16,7 +16,6 @@ package io.netty.handler.codec; import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerUtil; @@ -28,44 +27,41 @@ import io.netty.util.internal.Signal; * of a non-blocking decoder in the blocking I/O paradigm. *

* The biggest difference between {@link ReplayingDecoder} and - * {@link FrameDecoder} is that {@link ReplayingDecoder} allows you to + * {@link ByteToMessageDecoder} is that {@link ReplayingDecoder} allows you to * implement the {@code decode()} and {@code decodeLast()} methods just like * all required bytes were received already, rather than checking the * availability of the required bytes. For example, the following - * {@link FrameDecoder} implementation: + * {@link ByteToByteDecoder} implementation: *

- * public class IntegerHeaderFrameDecoder extends {@link FrameDecoder} {
+ * public class IntegerHeaderFrameDecoder extends {@link ByteToMessageDecoder}<{@link ByteBuf}> {
  *
  *   {@code @Override}
- *   protected Object decode({@link ChannelHandlerContext} ctx,
- *                           {@link Channel} channel,
- *                           {@link ByteBuf} buf) throws Exception {
+ *   protected ByteBuf decode({@link ChannelHandlerContext} ctx,
+ *                           {@link ByteBuf} in) throws Exception {
  *
- *     if (buf.readableBytes() < 4) {
+ *     if (in.readableBytes() < 4) {
  *        return null;
  *     }
  *
- *     buf.markReaderIndex();
- *     int length = buf.readInt();
+ *     in.markReaderIndex();
+ *     int length = in.readInt();
  *
- *     if (buf.readableBytes() < length) {
- *        buf.resetReaderIndex();
+ *     if (in.readableBytes() < length) {
+ *        in.resetReaderIndex();
  *        return null;
  *     }
  *
- *     return buf.readBytes(length);
+ *     return in.readBytes(length);
  *   }
  * }
  * 
* is simplified like the following with {@link ReplayingDecoder}: *
  * public class IntegerHeaderFrameDecoder
- *      extends {@link ReplayingDecoder}<{@link VoidEnum}> {
+ *      extends {@link ReplayingDecoder}<{@link ByteBuf},{@link Void}> {
  *
  *   protected Object decode({@link ChannelHandlerContext} ctx,
- *                           {@link Channel} channel,
- *                           {@link ByteBuf} buf,
- *                           {@link VoidEnum} state) throws Exception {
+ *                           {@link ByteBuf} buf) throws Exception {
  *
  *     return buf.readBytes(buf.readInt());
  *   }
@@ -104,12 +100,12 @@ import io.netty.util.internal.Signal;
  * 
  • You must keep in mind that {@code decode(..)} method can be called many * times to decode a single message. For example, the following code will * not work: - *
     public class MyDecoder extends {@link ReplayingDecoder}<{@link Void}> {
    + * 
     public class MyDecoder extends {@link ReplayingDecoder}<{@link Integer}, {@link Void}> {
      *
      *   private final Queue<Integer> values = new LinkedList<Integer>();
      *
      *   {@code @Override}
    - *   public Object decode(.., {@link ByteBuf} buffer, ..) throws Exception {
    + *   public {@link Integer} decode(.., {@link ByteBuf} in) throws Exception {
      *
      *     // A message contains 2 integers.
      *     values.offer(buffer.readInt());
    @@ -124,12 +120,12 @@ import io.netty.util.internal.Signal;
      *      The correct implementation looks like the following, and you can also
      *      utilize the 'checkpoint' feature which is explained in detail in the
      *      next section.
    - * 
     public class MyDecoder extends {@link ReplayingDecoder}<{@link Void}> {
    + * 
     public class MyDecoder extends {@link ReplayingDecoder}<{@link Integer}, {@link Void}> {
      *
      *   private final Queue<Integer> values = new LinkedList<Integer>();
      *
      *   {@code @Override}
    - *   public Object decode(.., {@link ByteBuf} buffer, ..) throws Exception {
    + *   public {@link Integer} decode(.., {@link ByteBuf} buffer) throws Exception {
      *
      *     // Revert the state of the variable that might have been changed
      *     // since the last partial decode.
    @@ -171,7 +167,7 @@ import io.netty.util.internal.Signal;
      * }
      *
      * public class IntegerHeaderFrameDecoder
    - *      extends {@link ReplayingDecoder}<MyDecoderState> {
    + *      extends {@link ReplayingDecoder}<{@link ByteBuf}, MyDecoderState> {
      *
      *   private int length;
      *
    @@ -181,16 +177,14 @@ import io.netty.util.internal.Signal;
      *   }
      *
      *   {@code @Override}
    - *   protected Object decode({@link ChannelHandlerContext} ctx,
    - *                           {@link Channel} channel,
    - *                           {@link ByteBuf} buf,
    - *                           MyDecoderState state) throws Exception {
    - *     switch (state) {
    + *   protected {@link ByteBuf} decode({@link ChannelHandlerContext} ctx,
    + *                           {@link ByteBuf} in) throws Exception {
    + *     switch (state()) {
      *     case READ_LENGTH:
      *       length = buf.readInt();
      *       checkpoint(MyDecoderState.READ_CONTENT);
      *     case READ_CONTENT:
    - *       ChannelBuffer frame = buf.readBytes(length);
    + *       ByteBuf frame = buf.readBytes(length);
      *       checkpoint(MyDecoderState.READ_LENGTH);
      *       return frame;
      *     default:
    @@ -205,16 +199,14 @@ import io.netty.util.internal.Signal;
      * An alternative way to manage the decoder state is to manage it by yourself.
      * 
      * public class IntegerHeaderFrameDecoder
    - *      extends {@link ReplayingDecoder}<{@link Void}> {
    + *      extends {@link ReplayingDecoder}<{@link ByteBuf},{@link Void}> {
      *
      *   private boolean readLength;
      *   private int length;
      *
      *   {@code @Override}
    - *   protected Object decode({@link ChannelHandlerContext} ctx,
    - *                           {@link Channel} channel,
    - *                           {@link ByteBuf} buf,
    - *                           {@link Void} state) throws Exception {
    + *   protected {@link ByteBuf} decode({@link ChannelHandlerContext} ctx,
    + *                           {@link ByteBuf} in) throws Exception {
      *     if (!readLength) {
      *       length = buf.readInt();
      *       readLength = true;
    @@ -222,7 +214,7 @@ import io.netty.util.internal.Signal;
      *     }
      *
      *     if (readLength) {
    - *       ChannelBuffer frame = buf.readBytes(length);
    + *       ByteBuf frame = buf.readBytes(length);
      *       readLength = false;
      *       checkpoint();
      *       return frame;
    @@ -235,31 +227,26 @@ import io.netty.util.internal.Signal;
      * 

    * If you are going to write a protocol multiplexer, you will probably want to * replace a {@link ReplayingDecoder} (protocol detector) with another - * {@link ReplayingDecoder} or {@link FrameDecoder} (actual protocol decoder). + * {@link ReplayingDecoder}, {@link ByteToByteDecoder}, {@link ByteToMessageDecoder} or {@link MessageToMessageDecoder} + * (actual protocol decoder). * It is not possible to achieve this simply by calling * {@link ChannelPipeline#replace(ChannelHandler, String, ChannelHandler)}, but * some additional steps are required: *

    - * public class FirstDecoder extends {@link ReplayingDecoder}<{@link Void}> {
    - *
    - *     public FirstDecoder() {
    - *         super(true); // Enable unfold
    - *     }
    + * public class FirstDecoder extends {@link ReplayingDecoder}<{@link Object}, {@link Void}> {
      *
      *     {@code @Override}
      *     protected Object decode({@link ChannelHandlerContext} ctx,
    - *                             {@link Channel} ch,
    - *                             {@link ByteBuf} buf,
    - *                             {@link Void} state) {
    + *                             {@link ByteBuf} in) {
      *         ...
      *         // Decode the first message
      *         Object firstMessage = ...;
      *
      *         // Add the second decoder
    - *         ctx.getPipeline().addLast("second", new SecondDecoder());
    + *         ctx.pipeline().addLast("second", new SecondDecoder());
      *
      *         // Remove the first decoder (me)
    - *         ctx.getPipeline().remove(this);
    + *         ctx.pipeline().remove(this);
      *
      *         if (buf.readable()) {
      *             // Hand off the remaining data to the second decoder
    diff --git a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoderBuffer.java b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoderBuffer.java
    index 28cf997c4d..c3e7f71544 100644
    --- a/codec/src/main/java/io/netty/handler/codec/ReplayingDecoderBuffer.java
    +++ b/codec/src/main/java/io/netty/handler/codec/ReplayingDecoderBuffer.java
    @@ -31,6 +31,9 @@ import java.nio.channels.GatheringByteChannel;
     import java.nio.channels.ScatteringByteChannel;
     import java.nio.charset.Charset;
     
    +/**
    + * Special {@link ByteBuf} implementation which is used by the {@link ReplayingDecoder}
    + */
     final class ReplayingDecoderBuffer implements ByteBuf {
     
         private static final Signal REPLAY = ReplayingDecoder.REPLAY;
    diff --git a/codec/src/main/java/io/netty/handler/codec/TooLongFrameException.java b/codec/src/main/java/io/netty/handler/codec/TooLongFrameException.java
    index 42704ead1e..74e4732486 100644
    --- a/codec/src/main/java/io/netty/handler/codec/TooLongFrameException.java
    +++ b/codec/src/main/java/io/netty/handler/codec/TooLongFrameException.java
    @@ -16,8 +16,8 @@
     package io.netty.handler.codec;
     
     /**
    - * An {@link Exception} which is thrown when the length of the frame
    - * decoded by {@link DelimiterBasedFrameDecoder} is greater than the maximum.
    + * An {@link DecoderException} which is thrown when the length of the frame
    + * decoded is greater than the allowed maximum.
      *
      * @apiviz.exclude
      */
    diff --git a/codec/src/main/java/io/netty/handler/codec/UnreplayableOperationException.java b/codec/src/main/java/io/netty/handler/codec/UnreplayableOperationException.java
    index f351ef73ac..7aef9ecaf3 100644
    --- a/codec/src/main/java/io/netty/handler/codec/UnreplayableOperationException.java
    +++ b/codec/src/main/java/io/netty/handler/codec/UnreplayableOperationException.java
    @@ -15,11 +15,9 @@
      */
     package io.netty.handler.codec;
     
    -import io.netty.buffer.ByteBuf;
    -
     /**
    - * An {@link Exception} which is thrown when a user calls an unsupported
    - * operation on a {@link ByteBuf} in a {@link ReplayingDecoder}
    + * An {@link UnsupportedOperationException} which is thrown when a user calls an unsupported
    + * operation on a {@link ReplayingDecoderBuffer} in a {@link ReplayingDecoder}
      * implementation.
      */
     public class UnreplayableOperationException extends UnsupportedOperationException {
    diff --git a/codec/src/main/java/io/netty/handler/codec/UnsupportedMessageTypeException.java b/codec/src/main/java/io/netty/handler/codec/UnsupportedMessageTypeException.java
    index b923f5ed1b..e81994bbda 100644
    --- a/codec/src/main/java/io/netty/handler/codec/UnsupportedMessageTypeException.java
    +++ b/codec/src/main/java/io/netty/handler/codec/UnsupportedMessageTypeException.java
    @@ -15,6 +15,9 @@
      */
     package io.netty.handler.codec;
     
    +/**
    + * Thrown if an unsupported message is received by an codec.
    + */
     public class UnsupportedMessageTypeException extends CodecException {
     
         private static final long serialVersionUID = 2799598826487038726L;
    diff --git a/handler/src/main/java/io/netty/handler/logging/LoggingHandler.java b/handler/src/main/java/io/netty/handler/logging/LoggingHandler.java
    index 93f6ca171e..0e9b7ade4c 100644
    --- a/handler/src/main/java/io/netty/handler/logging/LoggingHandler.java
    +++ b/handler/src/main/java/io/netty/handler/logging/LoggingHandler.java
    @@ -28,9 +28,7 @@ import java.net.SocketAddress;
     
     /**
      * A {@link ChannelHandler} that logs all events via {@link InternalLogger}.
    - * By default, all events are logged at DEBUG level.  You can extend
    - * this class and override {@link #log(ChannelEvent)} to change the default
    - * behavior.
    + * By default, all events are logged at DEBUG level.
      * @apiviz.landmark
      */
     @Sharable
    @@ -118,7 +116,6 @@ public class LoggingHandler extends ChannelHandlerAdapter {
     
         /**
          * Returns the {@link InternalLogLevel} that this handler uses to log
    -     * a {@link ChannelEvent}.
          */
         public LogLevel level() {
             return level;