1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.spdy.parser;
20
21 import java.nio.ByteBuffer;
22
23 import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
24
25 public class WindowUpdateBodyParser extends ControlFrameBodyParser
26 {
27 private final ControlFrameParser controlFrameParser;
28 private State state = State.STREAM_ID;
29 private int cursor;
30 private int streamId;
31 private int windowDelta;
32
33 public WindowUpdateBodyParser(ControlFrameParser controlFrameParser)
34 {
35 this.controlFrameParser = controlFrameParser;
36 }
37
38 @Override
39 public boolean parse(ByteBuffer buffer)
40 {
41 while (buffer.hasRemaining())
42 {
43 switch (state)
44 {
45 case STREAM_ID:
46 {
47 if (buffer.remaining() >= 4)
48 {
49 streamId = buffer.getInt() & 0x7F_FF_FF_FF;
50 state = State.WINDOW_DELTA;
51 }
52 else
53 {
54 state = State.STREAM_ID_BYTES;
55 cursor = 4;
56 }
57 break;
58 }
59 case STREAM_ID_BYTES:
60 {
61 byte currByte = buffer.get();
62 --cursor;
63 streamId += (currByte & 0xFF) << 8 * cursor;
64 if (cursor == 0)
65 {
66 streamId &= 0x7F_FF_FF_FF;
67 state = State.WINDOW_DELTA;
68 }
69 break;
70 }
71 case WINDOW_DELTA:
72 {
73 if (buffer.remaining() >= 4)
74 {
75 windowDelta = buffer.getInt() & 0x7F_FF_FF_FF;
76 onWindowUpdate();
77 return true;
78 }
79 else
80 {
81 state = State.WINDOW_DELTA_BYTES;
82 cursor = 4;
83 }
84 break;
85 }
86 case WINDOW_DELTA_BYTES:
87 {
88 byte currByte = buffer.get();
89 --cursor;
90 windowDelta += (currByte & 0xFF) << 8 * cursor;
91 if (cursor == 0)
92 {
93 windowDelta &= 0x7F_FF_FF_FF;
94 onWindowUpdate();
95 return true;
96 }
97 break;
98 }
99 default:
100 {
101 throw new IllegalStateException();
102 }
103 }
104 }
105 return false;
106 }
107
108 private void onWindowUpdate()
109 {
110 WindowUpdateFrame frame = new WindowUpdateFrame(controlFrameParser.getVersion(), streamId, windowDelta);
111 controlFrameParser.onControlFrame(frame);
112 reset();
113 }
114
115 private void reset()
116 {
117 state = State.STREAM_ID;
118 cursor = 0;
119 streamId = 0;
120 windowDelta = 0;
121 }
122
123 private enum State
124 {
125 STREAM_ID, STREAM_ID_BYTES, WINDOW_DELTA, WINDOW_DELTA_BYTES;
126 }
127 }