in lib/src/hpack/hpack.dart [66:162]
List<Header> decode(List<int> data) {
var offset = 0;
int readInteger(int prefixBits) {
assert(prefixBits <= 8 && prefixBits > 0);
var byte = data[offset++] & ((1 << prefixBits) - 1);
int integer;
if (byte == ((1 << prefixBits) - 1)) {
// Length encodeded.
integer = 0;
var shift = 0;
while (true) {
var done = (data[offset] & 0x80) != 0x80;
integer += (data[offset++] & 0x7f) << shift;
shift += 7;
if (done) break;
}
integer += (1 << prefixBits) - 1;
} else {
// In place length.
integer = byte;
}
return integer;
}
List<int> readStringLiteral() {
var isHuffmanEncoding = (data[offset] & 0x80) != 0;
var length = readInteger(7);
var sublist = viewOrSublist(data, offset, length);
offset += length;
if (isHuffmanEncoding) {
return http2HuffmanCodec.decode(sublist);
} else {
return sublist;
}
}
Header readHeaderFieldInternal(int index, {bool neverIndexed = false}) {
List<int> name, value;
if (index > 0) {
name = _table.lookup(index).name;
value = readStringLiteral();
} else {
name = readStringLiteral();
value = readStringLiteral();
}
return Header(name, value, neverIndexed: neverIndexed);
}
try {
var headers = <Header>[];
while (offset < data.length) {
var byte = data[offset];
var isIndexedField = (byte & 0x80) != 0;
var isIncrementalIndexing = (byte & 0xc0) == 0x40;
var isWithoutIndexing = (byte & 0xf0) == 0;
var isNeverIndexing = (byte & 0xf0) == 0x10;
var isDynamicTableSizeUpdate = (byte & 0xe0) == 0x20;
if (isIndexedField) {
var index = readInteger(7);
var field = _table.lookup(index);
headers.add(field);
} else if (isIncrementalIndexing) {
var field = readHeaderFieldInternal(readInteger(6));
_table.addHeaderField(field);
headers.add(field);
} else if (isWithoutIndexing) {
headers.add(readHeaderFieldInternal(readInteger(4)));
} else if (isNeverIndexing) {
headers
.add(readHeaderFieldInternal(readInteger(4), neverIndexed: true));
} else if (isDynamicTableSizeUpdate) {
var newMaxSize = readInteger(5);
if (newMaxSize <= _maxHeaderTableSize) {
_table.updateMaxSize(newMaxSize);
} else {
throw HPackDecodingException('Dynamic table size update failed: '
'A new value of $newMaxSize exceeds the limit of '
'$_maxHeaderTableSize');
}
} else {
throw HPackDecodingException('Invalid encoding of headers.');
}
}
return headers;
} on RangeError catch (e) {
throw HPackDecodingException('$e');
} on HuffmanDecodingException catch (e) {
throw HPackDecodingException('$e');
}
}