View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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 }