uint32_t HPACKDecoder::decodeIndexedHeader(HPACKDecodeBuffer& dbuf, headers_t* emitted) { uint32_t index; err_ = dbuf.decodeInteger(7, index); if (err_ != HPACK::DecodeError::NONE) { LOG(ERROR) << "Decode error decoding index err_=" << err_; return 0; } // validate the index if (index == 0 || !isValid(index)) { LOG(ERROR) << "received invalid index: " << index; err_ = HPACK::DecodeError::INVALID_INDEX; return 0; } uint32_t emittedSize = 0; if (isStatic(index)) { auto& header = getStaticHeader(index); emittedSize = emit(header, emitted); } else { auto& header = getDynamicHeader(index); emittedSize = emit(header, emitted); } return emittedSize; }
uint32_t HPACKDecoder::emitRefset(headers_t& emitted) { // emit the reference set std::sort(emitted.begin(), emitted.end()); list<uint32_t> refset = table_.referenceSet(); // remove the refset entries that have already been emitted list<uint32_t>::iterator refit = refset.begin(); while (refit != refset.end()) { const HPACKHeader& header = getDynamicHeader(dynamicToGlobalIndex(*refit)); if (std::binary_search(emitted.begin(), emitted.end(), header)) { refit = refset.erase(refit); } else { refit++; } } // try to avoid multiple resizing of the headers vector emitted.reserve(emitted.size() + refset.size()); uint32_t emittedSize = 0; for (const auto& index : refset) { emittedSize += emit(getDynamicHeader(dynamicToGlobalIndex(index)), emitted); } return emittedSize; }
uint32_t HPACKDecoder::decodeIndexedHeader(HPACKDecodeBuffer& dbuf, headers_t* emitted) { uint32_t index; err_ = dbuf.decodeInteger(7, index); if (err_ != DecodeError::NONE) { LOG(ERROR) << "Decode error decoding header index err_=" << err_; return 0; } if (index == 0) { table_.clearReferenceSet(); return 0; } // validate the index if (!isValid(index)) { LOG(ERROR) << "received invalid index: " << index; err_ = DecodeError::INVALID_INDEX; return 0; } uint32_t emittedSize = 0; // a static index cannot be part of the reference set if (isStatic(index)) { auto& header = getStaticHeader(index); emittedSize = emit(header, emitted); if (table_.add(header)) { table_.addReference(1); } } else if (table_.inReferenceSet(globalToDynamicIndex(index))) { // index remove operation table_.removeReference(globalToDynamicIndex(index)); } else { auto& header = getDynamicHeader(index); emittedSize = emit(header, emitted); table_.addReference(globalToDynamicIndex(index)); } return emittedSize; }