@@ -46,15 +46,25 @@ public class TransportFrameDecoder extends ChannelInboundHandlerAdapter {
46
46
47
47
public static final String HANDLER_NAME = "frameDecoder" ;
48
48
private static final int LENGTH_SIZE = 8 ;
49
+ private static final int MAX_FRAME_SIZE = Integer .MAX_VALUE ;
49
50
private static final int UNKNOWN_FRAME_SIZE = -1 ;
50
51
51
52
private final LinkedList <ByteBuf > buffers = new LinkedList <>();
52
53
private final ByteBuf frameLenBuf = Unpooled .buffer (LENGTH_SIZE , LENGTH_SIZE );
54
+ private final boolean isSupportLargeData ;
53
55
54
56
private long totalSize = 0 ;
55
57
private long nextFrameSize = UNKNOWN_FRAME_SIZE ;
56
58
private volatile Interceptor interceptor ;
57
59
60
+ public TransportFrameDecoder () {
61
+ this (true );
62
+ }
63
+
64
+ public TransportFrameDecoder (boolean isSupportLargeData ) {
65
+ this .isSupportLargeData = isSupportLargeData ;
66
+ }
67
+
58
68
@ Override
59
69
public void channelRead (ChannelHandlerContext ctx , Object data ) throws Exception {
60
70
ByteBuf in = (ByteBuf ) data ;
@@ -77,7 +87,13 @@ public void channelRead(ChannelHandlerContext ctx, Object data) throws Exception
77
87
totalSize -= read ;
78
88
} else {
79
89
// Interceptor is not active, so try to decode one frame.
80
- LinkedList <ByteBuf > frame = decodeNext ();
90
+ Object frame ;
91
+ if (isSupportLargeData ) {
92
+ frame = decodeList ();
93
+ } else {
94
+ frame = decodeByteBuf ();
95
+ }
96
+
81
97
if (frame == null ) {
82
98
break ;
83
99
}
@@ -120,7 +136,36 @@ private long decodeFrameSize() {
120
136
return nextFrameSize ;
121
137
}
122
138
123
- private LinkedList <ByteBuf > decodeNext () throws Exception {
139
+ private ByteBuf decodeByteBuf () throws Exception {
140
+ long frameSize = decodeFrameSize ();
141
+ if (frameSize == UNKNOWN_FRAME_SIZE || totalSize < frameSize ) {
142
+ return null ;
143
+ }
144
+
145
+ // Reset size for next frame.
146
+ nextFrameSize = UNKNOWN_FRAME_SIZE ;
147
+
148
+ Preconditions .checkArgument (frameSize < MAX_FRAME_SIZE , "Too large frame: %s" , frameSize );
149
+ Preconditions .checkArgument (frameSize > 0 , "Frame length should be positive: %s" , frameSize );
150
+
151
+ // If the first buffer holds the entire frame, return it.
152
+ int remaining = (int ) frameSize ;
153
+ if (buffers .getFirst ().readableBytes () >= remaining ) {
154
+ return nextBufferForFrame (remaining );
155
+ }
156
+
157
+ // Otherwise, create a composite buffer.
158
+ CompositeByteBuf frame = buffers .getFirst ().alloc ().compositeBuffer (Integer .MAX_VALUE );
159
+ while (remaining > 0 ) {
160
+ ByteBuf next = nextBufferForFrame (remaining );
161
+ remaining -= next .readableBytes ();
162
+ frame .addComponent (next ).writerIndex (frame .writerIndex () + next .readableBytes ());
163
+ }
164
+ assert remaining == 0 ;
165
+ return frame ;
166
+ }
167
+
168
+ private LinkedList <ByteBuf > decodeList () throws Exception {
124
169
long frameSize = decodeFrameSize ();
125
170
if (frameSize == UNKNOWN_FRAME_SIZE || totalSize < frameSize ) {
126
171
return null ;
0 commit comments