List decode()

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');
    }
  }