//======================================================================== //Copyright 2011-2012 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //All rights reserved. This program and the accompanying materials //are made available under the terms of the Eclipse Public License v1.0 //and Apache License v2.0 which accompanies this distribution. //The Eclipse Public License is available at //http://www.eclipse.org/legal/epl-v10.html //The Apache License v2.0 is available at //http://www.opensource.org/licenses/apache2.0.php //You may elect to redistribute this code under either of these licenses. //======================================================================== package org.eclipse.jetty.spdy.parser; import java.nio.ByteBuffer; import org.eclipse.jetty.spdy.frames.WindowUpdateFrame; public class WindowUpdateBodyParser extends ControlFrameBodyParser { private final ControlFrameParser controlFrameParser; private State state = State.STREAM_ID; private int cursor; private int streamId; private int windowDelta; public WindowUpdateBodyParser(ControlFrameParser controlFrameParser) { this.controlFrameParser = controlFrameParser; } @Override public boolean parse(ByteBuffer buffer) { while (buffer.hasRemaining()) { switch (state) { case STREAM_ID: { if (buffer.remaining() >= 4) { streamId = buffer.getInt() & 0x7F_FF_FF_FF; state = State.WINDOW_DELTA; } else { state = State.STREAM_ID_BYTES; cursor = 4; } break; } case STREAM_ID_BYTES: { byte currByte = buffer.get(); --cursor; streamId += (currByte & 0xFF) << 8 * cursor; if (cursor == 0) { streamId &= 0x7F_FF_FF_FF; state = State.WINDOW_DELTA; } break; } case WINDOW_DELTA: { if (buffer.remaining() >= 4) { windowDelta = buffer.getInt() & 0x7F_FF_FF_FF; onWindowUpdate(); return true; } else { state = State.WINDOW_DELTA_BYTES; cursor = 4; } break; } case WINDOW_DELTA_BYTES: { byte currByte = buffer.get(); --cursor; windowDelta += (currByte & 0xFF) << 8 * cursor; if (cursor == 0) { windowDelta &= 0x7F_FF_FF_FF; onWindowUpdate(); return true; } break; } default: { throw new IllegalStateException(); } } } return false; } private void onWindowUpdate() { WindowUpdateFrame frame = new WindowUpdateFrame(controlFrameParser.getVersion(), streamId, windowDelta); controlFrameParser.onControlFrame(frame); reset(); } private void reset() { state = State.STREAM_ID; cursor = 0; streamId = 0; windowDelta = 0; } private enum State { STREAM_ID, STREAM_ID_BYTES, WINDOW_DELTA, WINDOW_DELTA_BYTES; } }