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