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    *   http://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 org.jboss.netty.example.factorial;
    17
    18  import java.math.BigInteger;
    19
    20  import org.jboss.netty.buffer.ChannelBuffer;
    21  import org.jboss.netty.channel.Channel;
    22  import org.jboss.netty.channel.ChannelHandlerContext;
    23  import org.jboss.netty.handler.codec.frame.CorruptedFrameException;
    24  import org.jboss.netty.handler.codec.frame.FrameDecoder;
    25
    26  /**
    27   * Decodes the binary representation of a {@link BigInteger} prepended
    28   * with a magic number ('F' or 0x46) and a 32-bit integer length prefix into a
    29   * {@link BigInteger} instance.  For example, { 'F', 0, 0, 0, 1, 42 } will be
    30   * decoded into new BigInteger("42").
    31   */
    32  public class BigIntegerDecoder extends FrameDecoder {
    33
    34      @Override
    35      protected Object decode(
    36              ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
    37          // Wait until the length prefix is available.
    38          if (buffer.readableBytes() < 5) {
    39              return null;
    40          }
    41
    42          buffer.markReaderIndex();
    43
    44          // Check the magic number.
    45          int magicNumber = buffer.readUnsignedByte();
    46          if (magicNumber != 'F') {
    47              buffer.resetReaderIndex();
    48              throw new CorruptedFrameException(
    49                      "Invalid magic number: " + magicNumber);
    50          }
    51
    52          // Wait until the whole data is available.
    53          int dataLength = buffer.readInt();
    54          if (buffer.readableBytes() < dataLength) {
    55              buffer.resetReaderIndex();
    56              return null;
    57          }
    58
    59          // Convert the received data into a new BigInteger.
    60          byte[] decoded = new byte[dataLength];
    61          buffer.readBytes(decoded);
    62
    63          return new BigInteger(decoded);
    64      }
    65  }