View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty5.handler.codec;
17  
18  import io.netty5.buffer.api.Buffer;
19  import io.netty5.channel.ChannelHandlerContext;
20  
21  import static io.netty5.util.internal.ObjectUtil.checkPositive;
22  
23  /**
24   * A decoder that splits the received {@link Buffer}s by the fixed number
25   * of bytes. For example, if you received the following four fragmented packets:
26   * <pre>
27   * +---+----+------+----+
28   * | A | BC | DEFG | HI |
29   * +---+----+------+----+
30   * </pre>
31   * A {@link FixedLengthFrameDecoder}{@code (3)} will decode them into the
32   * following three packets with the fixed length:
33   * <pre>
34   * +-----+-----+-----+
35   * | ABC | DEF | GHI |
36   * +-----+-----+-----+
37   * </pre>
38   */
39  public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
40  
41      private final int frameLength;
42  
43      /**
44       * Creates a new instance.
45       *
46       * @param frameLength the length of the frame
47       */
48      public FixedLengthFrameDecoder(int frameLength) {
49          checkPositive(frameLength, "frameLength");
50          this.frameLength = frameLength;
51      }
52  
53      /**
54       * Creates a new instance.
55       *
56       * @param frameLength the length of the frame
57       */
58      public FixedLengthFrameDecoder(int frameLength, Cumulator cumulator) {
59          super(cumulator);
60          checkPositive(frameLength, "frameLength");
61          this.frameLength = frameLength;
62      }
63  
64      @Override
65      protected final void decode(ChannelHandlerContext ctx, Buffer in) throws Exception {
66          Object decoded = decode0(ctx, in);
67          if (decoded != null) {
68              ctx.fireChannelRead(decoded);
69          }
70      }
71  
72      /**
73       * Create a frame out of the {@link Buffer} and return it.
74       *
75       * @param   ctx             the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to
76       * @param   in              the {@link Buffer} from which to read data
77       * @return  frame           the {@link Buffer} which represent the frame or {@code null} if no frame could
78       *                          be created.
79       */
80      protected Object decode0(@SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, Buffer in)
81              throws Exception {
82          if (in.readableBytes() < frameLength) {
83              return null;
84          } else {
85              return in.readSplit(frameLength);
86          }
87      }
88  }