1 /*
2 * Copyright 2009 Red Hat, Inc.
3 *
4 * Red Hat licenses this file to you under the Apache License, version 2.0
5 * (the "License"); you may not use this file except in compliance with the
6 * 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 * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
33 * @author <a href="http://gleamynode.net/">Trustin Lee</a>
34 *
35 * @version $Rev: 2125 $, $Date: 2010-02-02 12:13:15 +0900 (Tue, 02 Feb 2010) $
36 */
37 public class BigIntegerDecoder extends FrameDecoder {
38
39 @Override
40 protected Object decode(
41 ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
42 // Wait until the length prefix is available.
43 if (buffer.readableBytes() < 5) {
44 return null;
45 }
46
47 buffer.markReaderIndex();
48
49 // Check the magic number.
50 int magicNumber = buffer.readUnsignedByte();
51 if (magicNumber != 'F') {
52 buffer.resetReaderIndex();
53 throw new CorruptedFrameException(
54 "Invalid magic number: " + magicNumber);
55 }
56
57 // Wait until the whole data is available.
58 int dataLength = buffer.readInt();
59 if (buffer.readableBytes() < dataLength) {
60 buffer.resetReaderIndex();
61 return null;
62 }
63
64 // Convert the received data into a new BigInteger.
65 byte[] decoded = new byte[dataLength];
66 buffer.readBytes(decoded);
67
68 return new BigInteger(decoded);
69 }
70 }