Use setPrefix API for NBitIntegerParser
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
12a64b1637
commit
9d9e13cf3a
|
@ -19,6 +19,7 @@ import org.eclipse.jetty.http.HttpField;
|
||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpTokens;
|
import org.eclipse.jetty.http.HttpTokens;
|
||||||
import org.eclipse.jetty.http.MetaData;
|
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.http3.qpack.table.Entry;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -59,6 +60,13 @@ public class QpackDecoder
|
||||||
_localMaxDynamicTableSize = localMaxdynamciTableSize;
|
_localMaxDynamicTableSize = localMaxdynamciTableSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface Handler
|
||||||
|
{
|
||||||
|
void onMetadata(MetaData metaData);
|
||||||
|
|
||||||
|
void onInstruction(Instruction instruction);
|
||||||
|
}
|
||||||
|
|
||||||
public MetaData decode(ByteBuffer buffer) throws QpackException.SessionException, QpackException.StreamException
|
public MetaData decode(ByteBuffer buffer) throws QpackException.SessionException, QpackException.StreamException
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
|
|
@ -26,11 +26,11 @@ public class DecoderInstructionParser
|
||||||
|
|
||||||
private final Handler _handler;
|
private final Handler _handler;
|
||||||
private final NBitIntegerParser _integerParser;
|
private final NBitIntegerParser _integerParser;
|
||||||
private State _state = State.PARSING;
|
private State _state = State.IDLE;
|
||||||
|
|
||||||
private enum State
|
private enum State
|
||||||
{
|
{
|
||||||
PARSING,
|
IDLE,
|
||||||
SECTION_ACKNOWLEDGEMENT,
|
SECTION_ACKNOWLEDGEMENT,
|
||||||
STREAM_CANCELLATION,
|
STREAM_CANCELLATION,
|
||||||
INSERT_COUNT_INCREMENT
|
INSERT_COUNT_INCREMENT
|
||||||
|
@ -58,22 +58,25 @@ public class DecoderInstructionParser
|
||||||
|
|
||||||
switch (_state)
|
switch (_state)
|
||||||
{
|
{
|
||||||
case PARSING:
|
case IDLE:
|
||||||
// Get first byte without incrementing the buffers position.
|
// Get first byte without incrementing the buffers position.
|
||||||
byte firstByte = buffer.get(buffer.position());
|
byte firstByte = buffer.get(buffer.position());
|
||||||
if ((firstByte & 0x80) != 0)
|
if ((firstByte & 0x80) != 0)
|
||||||
{
|
{
|
||||||
_state = State.SECTION_ACKNOWLEDGEMENT;
|
_state = State.SECTION_ACKNOWLEDGEMENT;
|
||||||
|
_integerParser.setPrefix(SECTION_ACKNOWLEDGEMENT_PREFIX);
|
||||||
parseSectionAcknowledgment(buffer);
|
parseSectionAcknowledgment(buffer);
|
||||||
}
|
}
|
||||||
else if ((firstByte & 0x40) != 0)
|
else if ((firstByte & 0x40) != 0)
|
||||||
{
|
{
|
||||||
_state = State.STREAM_CANCELLATION;
|
_state = State.STREAM_CANCELLATION;
|
||||||
|
_integerParser.setPrefix(STREAM_CANCELLATION_PREFIX);
|
||||||
parseStreamCancellation(buffer);
|
parseStreamCancellation(buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_state = State.INSERT_COUNT_INCREMENT;
|
_state = State.INSERT_COUNT_INCREMENT;
|
||||||
|
_integerParser.setPrefix(INSERT_COUNT_INCREMENT_PREFIX);
|
||||||
parseInsertCountIncrement(buffer);
|
parseInsertCountIncrement(buffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -97,31 +100,37 @@ public class DecoderInstructionParser
|
||||||
|
|
||||||
private void parseSectionAcknowledgment(ByteBuffer buffer)
|
private void parseSectionAcknowledgment(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
int streamId = _integerParser.decode(buffer, SECTION_ACKNOWLEDGEMENT_PREFIX);
|
int streamId = _integerParser.decode(buffer);
|
||||||
if (streamId >= 0)
|
if (streamId >= 0)
|
||||||
{
|
{
|
||||||
_state = State.PARSING;
|
reset();
|
||||||
_handler.onSectionAcknowledgement(streamId);
|
_handler.onSectionAcknowledgement(streamId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseStreamCancellation(ByteBuffer buffer)
|
private void parseStreamCancellation(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
int streamId = _integerParser.decode(buffer, STREAM_CANCELLATION_PREFIX);
|
int streamId = _integerParser.decode(buffer);
|
||||||
if (streamId >= 0)
|
if (streamId >= 0)
|
||||||
{
|
{
|
||||||
_state = State.PARSING;
|
reset();
|
||||||
_handler.onStreamCancellation(streamId);
|
_handler.onStreamCancellation(streamId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseInsertCountIncrement(ByteBuffer buffer)
|
private void parseInsertCountIncrement(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
int increment = _integerParser.decode(buffer, INSERT_COUNT_INCREMENT_PREFIX);
|
int increment = _integerParser.decode(buffer);
|
||||||
if (increment >= 0)
|
if (increment >= 0)
|
||||||
{
|
{
|
||||||
_state = State.PARSING;
|
reset();
|
||||||
_handler.onInsertCountIncrement(increment);
|
_handler.onInsertCountIncrement(increment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
_state = State.IDLE;
|
||||||
|
_integerParser.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,11 +89,13 @@ public class EncoderInstructionParser
|
||||||
else if ((firstByte & 0x20) != 0)
|
else if ((firstByte & 0x20) != 0)
|
||||||
{
|
{
|
||||||
_state = State.SET_CAPACITY;
|
_state = State.SET_CAPACITY;
|
||||||
|
_integerParser.setPrefix(5);
|
||||||
parseSetDynamicTableCapacity(buffer);
|
parseSetDynamicTableCapacity(buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_state = State.DUPLICATE;
|
_state = State.DUPLICATE;
|
||||||
|
_integerParser.setPrefix(5);
|
||||||
parseDuplicate(buffer);
|
parseDuplicate(buffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -129,24 +131,27 @@ public class EncoderInstructionParser
|
||||||
byte firstByte = buffer.get(buffer.position());
|
byte firstByte = buffer.get(buffer.position());
|
||||||
_referenceDynamicTable = (firstByte & 0x40) == 0;
|
_referenceDynamicTable = (firstByte & 0x40) == 0;
|
||||||
_operation = Operation.INDEX;
|
_operation = Operation.INDEX;
|
||||||
|
_integerParser.setPrefix(6);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case INDEX:
|
case INDEX:
|
||||||
_index = _integerParser.decode(buffer, 6);
|
_index = _integerParser.decode(buffer);
|
||||||
if (_index < 0)
|
if (_index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_stringParser.setPrefix(8);
|
|
||||||
_operation = Operation.VALUE;
|
_operation = Operation.VALUE;
|
||||||
|
_stringParser.setPrefix(8);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case VALUE:
|
case VALUE:
|
||||||
String value = _stringParser.decode(buffer);
|
String value = _stringParser.decode(buffer);
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return;
|
return;
|
||||||
_operation = Operation.NONE;
|
|
||||||
_state = State.PARSING;
|
int index = _index;
|
||||||
_handler.onInsertNameWithReference(_index, _referenceDynamicTable, value);
|
boolean dynamic = _referenceDynamicTable;
|
||||||
|
reset();
|
||||||
|
_handler.onInsertNameWithReference(index, dynamic, value);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -162,8 +167,8 @@ public class EncoderInstructionParser
|
||||||
switch (_operation)
|
switch (_operation)
|
||||||
{
|
{
|
||||||
case NONE:
|
case NONE:
|
||||||
_stringParser.setPrefix(6);
|
|
||||||
_operation = Operation.NAME;
|
_operation = Operation.NAME;
|
||||||
|
_stringParser.setPrefix(6);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case NAME:
|
case NAME:
|
||||||
|
@ -171,8 +176,8 @@ public class EncoderInstructionParser
|
||||||
if (_name == null)
|
if (_name == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_stringParser.setPrefix(8);
|
|
||||||
_operation = Operation.VALUE;
|
_operation = Operation.VALUE;
|
||||||
|
_stringParser.setPrefix(8);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case VALUE:
|
case VALUE:
|
||||||
|
@ -180,9 +185,9 @@ public class EncoderInstructionParser
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_operation = Operation.NONE;
|
String name = _name;
|
||||||
_state = State.PARSING;
|
reset();
|
||||||
_handler.onInsertWithLiteralName(_name, value);
|
_handler.onInsertWithLiteralName(name, value);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -193,21 +198,32 @@ public class EncoderInstructionParser
|
||||||
|
|
||||||
private void parseDuplicate(ByteBuffer buffer)
|
private void parseDuplicate(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
int index = _integerParser.decode(buffer, 5);
|
int index = _integerParser.decode(buffer);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
_state = State.PARSING;
|
reset();
|
||||||
_handler.onDuplicate(index);
|
_handler.onDuplicate(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseSetDynamicTableCapacity(ByteBuffer buffer)
|
private void parseSetDynamicTableCapacity(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
int capacity = _integerParser.decode(buffer, 5);
|
int capacity = _integerParser.decode(buffer);
|
||||||
if (capacity >= 0)
|
if (capacity >= 0)
|
||||||
{
|
{
|
||||||
_state = State.PARSING;
|
reset();
|
||||||
_handler.onSetDynamicTableCapacity(capacity);
|
_handler.onSetDynamicTableCapacity(capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
_stringParser.reset();
|
||||||
|
_integerParser.reset();
|
||||||
|
_state = State.PARSING;
|
||||||
|
_operation = Operation.NONE;
|
||||||
|
_referenceDynamicTable = false;
|
||||||
|
_index = -1;
|
||||||
|
_name = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,12 @@ public class NBitIntegerParser
|
||||||
private int _multiplier;
|
private int _multiplier;
|
||||||
private boolean _started;
|
private boolean _started;
|
||||||
|
|
||||||
public int decode(ByteBuffer buffer, int prefix)
|
public void setPrefix(int prefix)
|
||||||
|
{
|
||||||
|
_prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int decode(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
if (!_started)
|
if (!_started)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +35,6 @@ public class NBitIntegerParser
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
_started = true;
|
_started = true;
|
||||||
_prefix = prefix;
|
|
||||||
_multiplier = 1;
|
_multiplier = 1;
|
||||||
int nbits = 0xFF >>> (8 - _prefix);
|
int nbits = 0xFF >>> (8 - _prefix);
|
||||||
_total = buffer.get() & nbits;
|
_total = buffer.get() & nbits;
|
||||||
|
|
|
@ -59,10 +59,11 @@ public class NBitStringParser
|
||||||
byte firstByte = buffer.get(buffer.position());
|
byte firstByte = buffer.get(buffer.position());
|
||||||
_huffman = ((0x80 >>> (8 - _prefix)) & firstByte) != 0;
|
_huffman = ((0x80 >>> (8 - _prefix)) & firstByte) != 0;
|
||||||
_state = State.LENGTH;
|
_state = State.LENGTH;
|
||||||
|
_integerParser.setPrefix(_prefix - 1);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case LENGTH:
|
case LENGTH:
|
||||||
_length = _integerParser.decode(buffer, _prefix - 1);
|
_length = _integerParser.decode(buffer);
|
||||||
if (_length < 0)
|
if (_length < 0)
|
||||||
return null;
|
return null;
|
||||||
_state = State.VALUE;
|
_state = State.VALUE;
|
||||||
|
|
|
@ -37,10 +37,12 @@ public class NBitIntegerParserTest
|
||||||
ByteBuffer buffer1 = BufferUtil.toBuffer(bytes, 0, 2);
|
ByteBuffer buffer1 = BufferUtil.toBuffer(bytes, 0, 2);
|
||||||
ByteBuffer buffer2 = BufferUtil.toBuffer(bytes, 2, 1);
|
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));
|
assertThat(value, is(-1));
|
||||||
|
|
||||||
value = parser.decode(buffer2, 7);
|
parser.setPrefix(7);
|
||||||
|
value = parser.decode(buffer2);
|
||||||
assertThat(value, is(1337));
|
assertThat(value, is(1337));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue