void decode()

in proxygen/lib/http/codec/compress/experimental/simulator/QMINScheme.h [336:414]


  void decode(FrameFlags,
              std::unique_ptr<folly::IOBuf> encodedReq,
              SimStats &,
              SimStreamingCallback &callback) override {
    folly::io::Cursor cursor(encodedReq.get());
    const unsigned char *buf;
    ssize_t nread;
    size_t ctl_sz, stream_off;
    char outbuf[0x1000];
    unsigned name_len, val_len;
    unsigned decoded_size = 0;
    uint32_t stream_id;

    qms_ctl[1].out.qco_ctx = this;

    /* Read Stream ID: */
    buf = cursor.data();
    memcpy(&stream_id, buf, sizeof(uint32_t));
    encodedReq->trimStart(sizeof(uint32_t));

    /* Read size of control messages */
    buf = cursor.data();
    memcpy(&ctl_sz, buf, sizeof(ctl_sz));
    encodedReq->trimStart(sizeof(ctl_sz));

    /* Feed control messages to the decoder: */
    if (ctl_sz) {
      struct stream_chunk *chunk;

      /* Read stream offset: */
      buf = cursor.data();
      memcpy(&stream_off, buf, sizeof(stream_off));
      encodedReq->trimStart(sizeof(stream_off));

      buf = cursor.data();
      chunk = stream_chunk_new(stream_off, buf, ctl_sz);
      encodedReq->trimStart(ctl_sz);

      insert_chunk(&qms_streams[1], chunk);

      while ((chunk = maybe_pop_chunk(&qms_streams[1]))) {
        nread = qmin_dec_cmds_in(qms_dec, chunk->sc_buf, chunk->sc_sz);
        if (nread < 0 || (size_t)nread != chunk->sc_sz) {
          VLOG(1) << "error: qmin_dec_cmds_in failed";
          assert(0);
        }
        free(chunk);
      }
    }

    buf = cursor.data();
    const unsigned char *const end = buf + cursor.length();

    while (buf < end) {
      nread = qmin_dec_decode(
          qms_dec, buf, end - buf, outbuf, sizeof(outbuf), &name_len, &val_len);
      if (nread < 0) {
        VLOG(1) << "error: decoder failed!";
        assert(0);
        return;
      }
      assert(nread);
      buf += nread;
      decoded_size += name_len + val_len;
      std::string name{outbuf, name_len};
      std::string value{outbuf + name_len, val_len};
      callback.onHeader(HPACKHeaderName(folly::StringPiece(name)), value);
    }

    if (0 != qmin_dec_stream_done(qms_dec, stream_id)) {
      assert(0);
      VLOG(1) << "error: qmin_dec_stream_done failed";
    }

    proxygen::HTTPHeaderSize sz;
    sz.compressed = encodedReq->computeChainDataLength();
    sz.uncompressed = decoded_size;
    callback.onHeadersComplete(sz, true);
  }