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.ChannelHandlerContext;
26 import org.jboss.netty.channel.ChannelHandler.Sharable;
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
58
59
60
61 @Sharable
62 public class LengthFieldPrepender extends OneToOneEncoder {
63
64 private final int lengthFieldLength;
65 private final boolean lengthIncludesLengthFieldLength;
66
67
68
69
70
71
72
73
74
75
76 public LengthFieldPrepender(int lengthFieldLength) {
77 this(lengthFieldLength, false);
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 public LengthFieldPrepender(
94 int lengthFieldLength, boolean lengthIncludesLengthFieldLength) {
95 if (lengthFieldLength != 1 && lengthFieldLength != 2 &&
96 lengthFieldLength != 3 && lengthFieldLength != 4 &&
97 lengthFieldLength != 8) {
98 throw new IllegalArgumentException(
99 "lengthFieldLength must be either 1, 2, 3, 4, or 8: " +
100 lengthFieldLength);
101 }
102
103 this.lengthFieldLength = lengthFieldLength;
104 this.lengthIncludesLengthFieldLength = lengthIncludesLengthFieldLength;
105 }
106
107 @Override
108 protected Object encode(
109 ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
110 if (!(msg instanceof ChannelBuffer)) {
111 return msg;
112 }
113
114 ChannelBuffer body = (ChannelBuffer) msg;
115 ChannelBuffer header = channel.getConfig().getBufferFactory().getBuffer(body.order(), lengthFieldLength);
116
117 int length = lengthIncludesLengthFieldLength?
118 body.readableBytes() + lengthFieldLength : body.readableBytes();
119 switch (lengthFieldLength) {
120 case 1:
121 if (length >= 256) {
122 throw new IllegalArgumentException(
123 "length does not fit into a byte: " + length);
124 }
125 header.writeByte((byte) length);
126 break;
127 case 2:
128 if (length >= 65536) {
129 throw new IllegalArgumentException(
130 "length does not fit into a short integer: " + length);
131 }
132 header.writeShort((short) length);
133 break;
134 case 3:
135 if (length >= 16777216) {
136 throw new IllegalArgumentException(
137 "length does not fit into a medium integer: " + length);
138 }
139 header.writeMedium(length);
140 break;
141 case 4:
142 header.writeInt(length);
143 break;
144 case 8:
145 header.writeLong(length);
146 break;
147 default:
148 throw new Error("should not reach here");
149 }
150 return wrappedBuffer(header, body);
151 }
152 }