diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-09-29 16:16:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-11-09 10:04:06 +0000 |
commit | a95a7417ad456115a1ef2da4bb8320531c0821f1 (patch) | |
tree | edcd59279e486d2fd4a8f88a7ed025bcf925c6e6 /chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc | |
parent | 33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (diff) | |
download | qtwebengine-chromium-a95a7417ad456115a1ef2da4bb8320531c0821f1.tar.gz |
BASELINE: Update Chromium to 106.0.5249.126
Change-Id: Ib0bb21c437a7d1686e21c33f2d329f2ac425b7ab
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438936
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc')
-rw-r--r-- | chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc b/chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc index 52b4af4aeae..080431c0b6b 100644 --- a/chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc +++ b/chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc @@ -143,6 +143,94 @@ bool QuicheDataReader::ReadDecimal64(size_t num_digits, uint64_t* result) { return absl::SimpleAtoi(digits, result); } +QuicheVariableLengthIntegerLength QuicheDataReader::PeekVarInt62Length() { + QUICHE_DCHECK_EQ(endianness(), NETWORK_BYTE_ORDER); + const unsigned char* next = + reinterpret_cast<const unsigned char*>(data() + pos()); + if (BytesRemaining() == 0) { + return VARIABLE_LENGTH_INTEGER_LENGTH_0; + } + return static_cast<QuicheVariableLengthIntegerLength>( + 1 << ((*next & 0b11000000) >> 6)); +} + +// Read an RFC 9000 62-bit Variable Length Integer. +// +// Performance notes +// +// Measurements and experiments showed that unrolling the four cases +// like this and dereferencing next_ as we do (*(next_+n) --- and then +// doing a single pos_+=x at the end) gains about 10% over making a +// loop and dereferencing next_ such as *(next_++) +// +// Using a register for pos_ was not helpful. +// +// Branches are ordered to increase the likelihood of the first being +// taken. +// +// Low-level optimization is useful here because this function will be +// called frequently, leading to outsize benefits. +bool QuicheDataReader::ReadVarInt62(uint64_t* result) { + QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER); + + size_t remaining = BytesRemaining(); + const unsigned char* next = + reinterpret_cast<const unsigned char*>(data() + pos()); + if (remaining != 0) { + switch (*next & 0xc0) { + case 0xc0: + // Leading 0b11...... is 8 byte encoding + if (remaining >= 8) { + *result = (static_cast<uint64_t>((*(next)) & 0x3f) << 56) + + (static_cast<uint64_t>(*(next + 1)) << 48) + + (static_cast<uint64_t>(*(next + 2)) << 40) + + (static_cast<uint64_t>(*(next + 3)) << 32) + + (static_cast<uint64_t>(*(next + 4)) << 24) + + (static_cast<uint64_t>(*(next + 5)) << 16) + + (static_cast<uint64_t>(*(next + 6)) << 8) + + (static_cast<uint64_t>(*(next + 7)) << 0); + AdvancePos(8); + return true; + } + return false; + + case 0x80: + // Leading 0b10...... is 4 byte encoding + if (remaining >= 4) { + *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) + + (((*(next + 2)) << 8)) + (((*(next + 3)) << 0)); + AdvancePos(4); + return true; + } + return false; + + case 0x40: + // Leading 0b01...... is 2 byte encoding + if (remaining >= 2) { + *result = (((*(next)) & 0x3f) << 8) + (*(next + 1)); + AdvancePos(2); + return true; + } + return false; + + case 0x00: + // Leading 0b00...... is 1 byte encoding + *result = (*next) & 0x3f; + AdvancePos(1); + return true; + } + } + return false; +} + +bool QuicheDataReader::ReadStringPieceVarInt62(absl::string_view* result) { + uint64_t result_length; + if (!ReadVarInt62(&result_length)) { + return false; + } + return ReadStringPiece(result, result_length); +} + absl::string_view QuicheDataReader::ReadRemainingPayload() { absl::string_view payload = PeekRemainingPayload(); pos_ = len_; |