1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.frame;
17
18 import static org.jboss.netty.buffer.ChannelBuffers.*;
19
20 import java.nio.ByteOrder;
21
22 import org.jboss.netty.buffer.ChannelBuffer;
23 import org.jboss.netty.buffer.ChannelBufferFactory;
24 import org.jboss.netty.channel.Channel;
25 import org.jboss.netty.channel.ChannelHandler.Sharable;
26 import org.jboss.netty.channel.ChannelHandlerContext;
27 import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 @Sharable
58 public class LengthFieldPrepender extends OneToOneEncoder {
59
60 private final int lengthFieldLength;
61 private final boolean lengthIncludesLengthFieldLength;
62
63
64
65
66
67
68
69
70
71
72 public LengthFieldPrepender(int lengthFieldLength) {
73 this(lengthFieldLength, false);
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public LengthFieldPrepender(
90 int lengthFieldLength, boolean lengthIncludesLengthFieldLength) {
91 if (lengthFieldLength != 1 && lengthFieldLength != 2 &&
92 lengthFieldLength != 3 && lengthFieldLength != 4 &&
93 lengthFieldLength != 8) {
94 throw new IllegalArgumentException(
95 "lengthFieldLength must be either 1, 2, 3, 4, or 8: " +
96 lengthFieldLength);
97 }
98
99 this.lengthFieldLength = lengthFieldLength;
100 this.lengthIncludesLengthFieldLength = lengthIncludesLengthFieldLength;
101 }
102
103 @Override
104 protected Object encode(
105 ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
106 if (!(msg instanceof ChannelBuffer)) {
107 return msg;
108 }
109
110 ChannelBuffer body = (ChannelBuffer) msg;
111 ChannelBuffer header = channel.getConfig().getBufferFactory().getBuffer(body.order(), lengthFieldLength);
112
113 int length = lengthIncludesLengthFieldLength?
114 body.readableBytes() + lengthFieldLength : body.readableBytes();
115 switch (lengthFieldLength) {
116 case 1:
117 if (length >= 256) {
118 throw new IllegalArgumentException(
119 "length does not fit into a byte: " + length);
120 }
121 header.writeByte((byte) length);
122 break;
123 case 2:
124 if (length >= 65536) {
125 throw new IllegalArgumentException(
126 "length does not fit into a short integer: " + length);
127 }
128 header.writeShort((short) length);
129 break;
130 case 3:
131 if (length >= 16777216) {
132 throw new IllegalArgumentException(
133 "length does not fit into a medium integer: " + length);
134 }
135 header.writeMedium(length);
136 break;
137 case 4:
138 header.writeInt(length);
139 break;
140 case 8:
141 header.writeLong(length);
142 break;
143 default:
144 throw new Error("should not reach here");
145 }
146 return wrappedBuffer(header, body);
147 }
148 }