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