in proxygen/lib/http/codec/compress/experimental/interop/QPACKInterop.cpp [319:382]
void onIngress(folly::IOBufQueue& input) override {
Cursor c(input.front());
while (!c.isAtEnd()) {
switch (state_) {
case LINESTART: {
seenR = false;
auto p = c.peek();
switch (p.first[0]) {
case '#':
state_ = COMMENT;
break;
case '\r':
case '\n':
if (!blocks.back().empty()) {
blocks.emplace_back();
}
state_ = EOL;
break;
default:
state_ = NAME;
strings.emplace_back();
}
break;
}
case COMMENT:
c.skipWhile([](uint8_t ch) { return !iseol(ch); });
if (!c.isAtEnd()) {
state_ = EOL;
}
break;
case EOL: {
auto p = c.peek();
if (p.first[0] == '\n') {
c.skip(1);
state_ = LINESTART;
} else if (seenR) { // \r followed by anything but \n -> mac newline
state_ = LINESTART;
} else if (p.first[0] == '\r') {
c.skip(1);
seenR = true;
}
break;
}
case NAME:
strings.back() += c.readWhile([](uint8_t ch) { return ch != '\t'; });
if (!c.isAtEnd()) {
c.skip(1);
state_ = VALUE;
strings.emplace_back();
}
break;
case VALUE:
strings.back() += c.readWhile([](uint8_t ch) { return !iseol(ch); });
if (!c.isAtEnd()) {
CHECK_GE(strings.size(), 2);
blocks.back().emplace_back(compress::Header::makeHeaderForTest(
*(strings.rbegin() + 1), *strings.rbegin()));
state_ = EOL;
}
break;
}
}
input.move();
}