summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-09-29 16:16:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 10:04:06 +0000
commita95a7417ad456115a1ef2da4bb8320531c0821f1 (patch)
treeedcd59279e486d2fd4a8f88a7ed025bcf925c6e6 /chromium/net/third_party/quiche/src/quiche/common/quiche_data_reader.cc
parent33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (diff)
downloadqtwebengine-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.cc88
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_;