All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.firefly.codec.http2.decode.PingBodyParser Maven / Gradle / Ivy

There is a newer version: 5.0.0-dev6
Show newest version
package com.firefly.codec.http2.decode;

import java.nio.ByteBuffer;

import com.firefly.codec.http2.frame.ErrorCode;
import com.firefly.codec.http2.frame.Flags;
import com.firefly.codec.http2.frame.PingFrame;

public class PingBodyParser extends BodyParser {
	private State state = State.PREPARE;
	private int cursor;
	private byte[] payload;

	public PingBodyParser(HeaderParser headerParser, Parser.Listener listener) {
		super(headerParser, listener);
	}

	private void reset() {
		state = State.PREPARE;
		cursor = 0;
		payload = null;
	}

	@Override
	public boolean parse(ByteBuffer buffer) {
		while (buffer.hasRemaining()) {
			switch (state) {
			case PREPARE: {
				// SPEC: wrong streamId is treated as connection error.
				if (getStreamId() != 0)
					return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_ping_frame");
				// SPEC: wrong body length is treated as connection error.
				if (getBodyLength() != 8)
					return connectionFailure(buffer, ErrorCode.FRAME_SIZE_ERROR.code, "invalid_ping_frame");
				state = State.PAYLOAD;
				break;
			}
			case PAYLOAD: {
				payload = new byte[8];
				if (buffer.remaining() >= 8) {
					buffer.get(payload);
					return onPing(payload);
				} else {
					state = State.PAYLOAD_BYTES;
					cursor = 8;
				}
				break;
			}
			case PAYLOAD_BYTES: {
				payload[8 - cursor] = buffer.get();
				--cursor;
				if (cursor == 0)
					return onPing(payload);
				break;
			}
			default: {
				throw new IllegalStateException();
			}
			}
		}
		return false;
	}

	private boolean onPing(byte[] payload) {
		PingFrame frame = new PingFrame(payload, hasFlag(Flags.ACK));
		reset();
		notifyPing(frame);
		return true;
	}

	private enum State {
		PREPARE, PAYLOAD, PAYLOAD_BYTES
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy