1 /**
2 This file is part of GoldenGate Project (named also GoldenGate or GG).
3
4 Copyright 2009, Frederic Bregier, and individual contributors by the @author
5 tags. See the COPYRIGHT.txt in the distribution for a full listing of
6 individual contributors.
7
8 All GoldenGate Project is free software: you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as published
10 by the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 GoldenGate is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GoldenGate . If not, see <http://www.gnu.org/licenses/>.
20 */
21 package openr66.protocol.localhandler.packet;
22
23 import goldengate.common.exception.InvalidArgumentException;
24 import openr66.protocol.exception.OpenR66ProtocolPacketException;
25
26 import org.jboss.netty.buffer.ChannelBuffer;
27 import org.jboss.netty.channel.Channel;
28 import org.jboss.netty.channel.ChannelDownstreamHandler;
29 import org.jboss.netty.channel.ChannelEvent;
30 import org.jboss.netty.channel.ChannelHandlerContext;
31 import org.jboss.netty.channel.Channels;
32 import org.jboss.netty.channel.MessageEvent;
33 import org.jboss.netty.handler.codec.frame.FrameDecoder;
34
35 /**
36 * Local Packet Decoder
37 *
38 * @author Frederic Bregier
39 */
40 public class LocalPacketCodec extends FrameDecoder implements
41 ChannelDownstreamHandler {
42
43 /*
44 * (non-Javadoc)
45 *
46 * @see
47 * org.jboss.netty.handler.codec.frame.FrameDecoder#decode(org.jboss.netty
48 * .channel.ChannelHandlerContext, org.jboss.netty.channel.Channel,
49 * org.jboss.netty.buffer.ChannelBuffer)
50 */
51 @Override
52 protected Object decode(ChannelHandlerContext ctx, Channel channel,
53 ChannelBuffer buf) throws Exception {
54 // Make sure if the length field was received.
55 if (buf.readableBytes() < 4) {
56 // The length field was not received yet - return null.
57 // This method will be invoked again when more packets are
58 // received and appended to the buffer.
59 return null;
60 }
61 return decodeNetworkPacket(buf);
62 }
63
64 public static AbstractLocalPacket decodeNetworkPacket(ChannelBuffer buf)
65 throws OpenR66ProtocolPacketException {
66 // Mark the current buffer position
67 buf.markReaderIndex();
68 // Read the length field
69 final int length = buf.readInt();
70 if (buf.readableBytes() < length) {
71 buf.resetReaderIndex();
72 return null;
73 }
74 // Now we can read the header
75 // Header: Header length field (4 bytes) = Middle length field (4
76 // bytes), End length field (4 bytes), type field (1 byte), ...
77 final int middleLength = buf.readInt();
78 final int endLength = buf.readInt();
79 // check if the packet is complete
80 if (middleLength + endLength + length - 8 > buf.readableBytes()) {
81 buf.resetReaderIndex();
82 return null;
83 }
84 // createPacketFromChannelBuffer read the buffer
85 return LocalPacketFactory.createPacketFromChannelBuffer(length - 8,
86 middleLength, endLength, buf);
87 }
88
89 @Override
90 public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)
91 throws Exception {
92 if (e instanceof MessageEvent) {
93 final MessageEvent evt = (MessageEvent) e;
94 if (evt.getMessage() instanceof ChannelBuffer) {
95 Channels.write(ctx, evt.getFuture(), evt.getMessage());
96 return;
97 }
98 if (!(evt.getMessage() instanceof AbstractLocalPacket)) {
99 throw new InvalidArgumentException("Incorrect write object: " +
100 evt.getMessage().getClass().getName());
101 }
102 final AbstractLocalPacket packet = (AbstractLocalPacket) evt
103 .getMessage();
104 final ChannelBuffer buf = packet.getLocalPacket();
105 Channels.write(ctx, evt.getFuture(), buf);
106 } else {
107 ctx.sendDownstream(e);
108 }
109 }
110
111 }