Use setPrefix API for NBitIntegerParser

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2021-02-13 01:54:10 +11:00 committed by Simone Bordet
parent 12a64b1637
commit 9d9e13cf3a
6 changed files with 68 additions and 28 deletions

View File

@ -19,6 +19,7 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpTokens;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http3.qpack.generator.Instruction;
import org.eclipse.jetty.http3.qpack.table.Entry;
import org.eclipse.jetty.util.BufferUtil;
import org.slf4j.Logger;
@ -59,6 +60,13 @@ public class QpackDecoder
_localMaxDynamicTableSize = localMaxdynamciTableSize;
}
public interface Handler
{
void onMetadata(MetaData metaData);
void onInstruction(Instruction instruction);
}
public MetaData decode(ByteBuffer buffer) throws QpackException.SessionException, QpackException.StreamException
{
if (LOG.isDebugEnabled())

View File

@ -26,11 +26,11 @@ public class DecoderInstructionParser
private final Handler _handler;
private final NBitIntegerParser _integerParser;
private State _state = State.PARSING;
private State _state = State.IDLE;
private enum State
{
PARSING,
IDLE,
SECTION_ACKNOWLEDGEMENT,
STREAM_CANCELLATION,
INSERT_COUNT_INCREMENT
@ -58,22 +58,25 @@ public class DecoderInstructionParser
switch (_state)
{
case PARSING:
case IDLE:
// Get first byte without incrementing the buffers position.
byte firstByte = buffer.get(buffer.position());
if ((firstByte & 0x80) != 0)
{
_state = State.SECTION_ACKNOWLEDGEMENT;
_integerParser.setPrefix(SECTION_ACKNOWLEDGEMENT_PREFIX);
parseSectionAcknowledgment(buffer);
}
else if ((firstByte & 0x40) != 0)
{
_state = State.STREAM_CANCELLATION;
_integerParser.setPrefix(STREAM_CANCELLATION_PREFIX);
parseStreamCancellation(buffer);
}
else
{
_state = State.INSERT_COUNT_INCREMENT;
_integerParser.setPrefix(INSERT_COUNT_INCREMENT_PREFIX);
parseInsertCountIncrement(buffer);
}
break;
@ -97,31 +100,37 @@ public class DecoderInstructionParser
private void parseSectionAcknowledgment(ByteBuffer buffer)
{
int streamId = _integerParser.decode(buffer, SECTION_ACKNOWLEDGEMENT_PREFIX);
int streamId = _integerParser.decode(buffer);
if (streamId >= 0)
{
_state = State.PARSING;
reset();
_handler.onSectionAcknowledgement(streamId);
}
}
private void parseStreamCancellation(ByteBuffer buffer)
{
int streamId = _integerParser.decode(buffer, STREAM_CANCELLATION_PREFIX);
int streamId = _integerParser.decode(buffer);
if (streamId >= 0)
{
_state = State.PARSING;
reset();
_handler.onStreamCancellation(streamId);
}
}
private void parseInsertCountIncrement(ByteBuffer buffer)
{
int increment = _integerParser.decode(buffer, INSERT_COUNT_INCREMENT_PREFIX);
int increment = _integerParser.decode(buffer);
if (increment >= 0)
{
_state = State.PARSING;
reset();
_handler.onInsertCountIncrement(increment);
}
}
public void reset()
{
_state = State.IDLE;
_integerParser.reset();
}
}

View File

@ -89,11 +89,13 @@ public class EncoderInstructionParser
else if ((firstByte & 0x20) != 0)
{
_state = State.SET_CAPACITY;
_integerParser.setPrefix(5);
parseSetDynamicTableCapacity(buffer);
}
else
{
_state = State.DUPLICATE;
_integerParser.setPrefix(5);
parseDuplicate(buffer);
}
break;
@ -129,24 +131,27 @@ public class EncoderInstructionParser
byte firstByte = buffer.get(buffer.position());
_referenceDynamicTable = (firstByte & 0x40) == 0;
_operation = Operation.INDEX;
_integerParser.setPrefix(6);
continue;
case INDEX:
_index = _integerParser.decode(buffer, 6);
_index = _integerParser.decode(buffer);
if (_index < 0)
return;
_stringParser.setPrefix(8);
_operation = Operation.VALUE;
_stringParser.setPrefix(8);
continue;
case VALUE:
String value = _stringParser.decode(buffer);
if (value == null)
return;
_operation = Operation.NONE;
_state = State.PARSING;
_handler.onInsertNameWithReference(_index, _referenceDynamicTable, value);
int index = _index;
boolean dynamic = _referenceDynamicTable;
reset();
_handler.onInsertNameWithReference(index, dynamic, value);
return;
default:
@ -162,8 +167,8 @@ public class EncoderInstructionParser
switch (_operation)
{
case NONE:
_stringParser.setPrefix(6);
_operation = Operation.NAME;
_stringParser.setPrefix(6);
continue;
case NAME:
@ -171,8 +176,8 @@ public class EncoderInstructionParser
if (_name == null)
return;
_stringParser.setPrefix(8);
_operation = Operation.VALUE;
_stringParser.setPrefix(8);
continue;
case VALUE:
@ -180,9 +185,9 @@ public class EncoderInstructionParser
if (value == null)
return;
_operation = Operation.NONE;
_state = State.PARSING;
_handler.onInsertWithLiteralName(_name, value);
String name = _name;
reset();
_handler.onInsertWithLiteralName(name, value);
return;
default:
@ -193,21 +198,32 @@ public class EncoderInstructionParser
private void parseDuplicate(ByteBuffer buffer)
{
int index = _integerParser.decode(buffer, 5);
int index = _integerParser.decode(buffer);
if (index >= 0)
{
_state = State.PARSING;
reset();
_handler.onDuplicate(index);
}
}
private void parseSetDynamicTableCapacity(ByteBuffer buffer)
{
int capacity = _integerParser.decode(buffer, 5);
int capacity = _integerParser.decode(buffer);
if (capacity >= 0)
{
_state = State.PARSING;
reset();
_handler.onSetDynamicTableCapacity(capacity);
}
}
public void reset()
{
_stringParser.reset();
_integerParser.reset();
_state = State.PARSING;
_operation = Operation.NONE;
_referenceDynamicTable = false;
_index = -1;
_name = null;
}
}

View File

@ -22,7 +22,12 @@ public class NBitIntegerParser
private int _multiplier;
private boolean _started;
public int decode(ByteBuffer buffer, int prefix)
public void setPrefix(int prefix)
{
_prefix = prefix;
}
public int decode(ByteBuffer buffer)
{
if (!_started)
{
@ -30,7 +35,6 @@ public class NBitIntegerParser
return -1;
_started = true;
_prefix = prefix;
_multiplier = 1;
int nbits = 0xFF >>> (8 - _prefix);
_total = buffer.get() & nbits;

View File

@ -59,10 +59,11 @@ public class NBitStringParser
byte firstByte = buffer.get(buffer.position());
_huffman = ((0x80 >>> (8 - _prefix)) & firstByte) != 0;
_state = State.LENGTH;
_integerParser.setPrefix(_prefix - 1);
continue;
case LENGTH:
_length = _integerParser.decode(buffer, _prefix - 1);
_length = _integerParser.decode(buffer);
if (_length < 0)
return null;
_state = State.VALUE;

View File

@ -37,10 +37,12 @@ public class NBitIntegerParserTest
ByteBuffer buffer1 = BufferUtil.toBuffer(bytes, 0, 2);
ByteBuffer buffer2 = BufferUtil.toBuffer(bytes, 2, 1);
int value = parser.decode(buffer1, 7);
parser.setPrefix(7);
int value = parser.decode(buffer1);
assertThat(value, is(-1));
value = parser.decode(buffer2, 7);
parser.setPrefix(7);
value = parser.decode(buffer2);
assertThat(value, is(1337));
}
}