xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_data_reader.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/quic_data_reader.h"
6 
7 #include "absl/strings/string_view.h"
8 #include "quiche/quic/core/quic_packets.h"
9 #include "quiche/quic/core/quic_utils.h"
10 #include "quiche/quic/platform/api/quic_bug_tracker.h"
11 #include "quiche/quic/platform/api/quic_flags.h"
12 #include "quiche/common/quiche_endian.h"
13 
14 namespace quic {
15 
QuicDataReader(absl::string_view data)16 QuicDataReader::QuicDataReader(absl::string_view data)
17     : quiche::QuicheDataReader(data) {}
18 
QuicDataReader(const char * data,const size_t len)19 QuicDataReader::QuicDataReader(const char* data, const size_t len)
20     : QuicDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {}
21 
QuicDataReader(const char * data,const size_t len,quiche::Endianness endianness)22 QuicDataReader::QuicDataReader(const char* data, const size_t len,
23                                quiche::Endianness endianness)
24     : quiche::QuicheDataReader(data, len, endianness) {}
25 
ReadUFloat16(uint64_t * result)26 bool QuicDataReader::ReadUFloat16(uint64_t* result) {
27   uint16_t value;
28   if (!ReadUInt16(&value)) {
29     return false;
30   }
31 
32   *result = value;
33   if (*result < (1 << kUFloat16MantissaEffectiveBits)) {
34     // Fast path: either the value is denormalized (no hidden bit), or
35     // normalized (hidden bit set, exponent offset by one) with exponent zero.
36     // Zero exponent offset by one sets the bit exactly where the hidden bit is.
37     // So in both cases the value encodes itself.
38     return true;
39   }
40 
41   uint16_t exponent =
42       value >> kUFloat16MantissaBits;  // No sign extend on uint!
43   // After the fast pass, the exponent is at least one (offset by one).
44   // Un-offset the exponent.
45   --exponent;
46   QUICHE_DCHECK_GE(exponent, 1);
47   QUICHE_DCHECK_LE(exponent, kUFloat16MaxExponent);
48   // Here we need to clear the exponent and set the hidden bit. We have already
49   // decremented the exponent, so when we subtract it, it leaves behind the
50   // hidden bit.
51   *result -= exponent << kUFloat16MantissaBits;
52   *result <<= exponent;
53   QUICHE_DCHECK_GE(*result,
54                    static_cast<uint64_t>(1 << kUFloat16MantissaEffectiveBits));
55   QUICHE_DCHECK_LE(*result, kUFloat16MaxValue);
56   return true;
57 }
58 
ReadConnectionId(QuicConnectionId * connection_id,uint8_t length)59 bool QuicDataReader::ReadConnectionId(QuicConnectionId* connection_id,
60                                       uint8_t length) {
61   if (length == 0) {
62     connection_id->set_length(0);
63     return true;
64   }
65 
66   if (BytesRemaining() < length) {
67     return false;
68   }
69 
70   connection_id->set_length(length);
71   const bool ok =
72       ReadBytes(connection_id->mutable_data(), connection_id->length());
73   QUICHE_DCHECK(ok);
74   return ok;
75 }
76 
ReadLengthPrefixedConnectionId(QuicConnectionId * connection_id)77 bool QuicDataReader::ReadLengthPrefixedConnectionId(
78     QuicConnectionId* connection_id) {
79   uint8_t connection_id_length;
80   if (!ReadUInt8(&connection_id_length)) {
81     return false;
82   }
83   return ReadConnectionId(connection_id, connection_id_length);
84 }
85 
86 #undef ENDPOINT  // undef for jumbo builds
87 }  // namespace quic
88