byte fin = (byte) (b & 0x80);
byte reserved = (byte) (b & 0x70);
byte opcode = (byte) (b & 0x0F);
if (reserved != 0) {
throw new CorruptedFrameException("Reserved bits set: " + bits(reserved));
}
if (!isOpcode(opcode)) {
throw new CorruptedFrameException("Invalid opcode " + hex(opcode));
}
if (fin == 0) {
if (fragmentOpcode == null) {
if (!isDataOpcode(opcode)) {
throw new CorruptedFrameException("Fragmented frame with invalid opcode " + hex(opcode));
}
fragmentOpcode = opcode;
} else if (opcode != OPCODE_CONT) {
throw new CorruptedFrameException("Continuation frame with invalid opcode " + hex(opcode));
}
} else {
if (fragmentOpcode != null) {
if (!isControlOpcode(opcode) && opcode != OPCODE_CONT) {
throw new CorruptedFrameException("Final frame with invalid opcode " + hex(opcode));
}
} else if (opcode == OPCODE_CONT) {
throw new CorruptedFrameException("Final frame with invalid opcode " + hex(opcode));
}
this.opcode = opcode;
}
checkpoint(State.PARSING_LENGTH);
case PARSING_LENGTH:
b = buffer.readByte();
byte masked = (byte) (b & 0x80);
if (masked == 0) {
throw new CorruptedFrameException("Unmasked frame received");
}
int length = (byte) (b & 0x7F);
if (length < 126) {
currentFrameLength = length;