• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "net/quic/quic_data_reader.h"
6 
7 #include "net/base/int128.h"
8 #include "net/quic/quic_protocol.h"
9 
10 using base::StringPiece;
11 
12 namespace net {
13 
QuicDataReader(const char * data,const size_t len)14 QuicDataReader::QuicDataReader(const char* data, const size_t len)
15     : data_(data),
16       len_(len),
17       pos_(0) {
18 }
19 
ReadUInt16(uint16 * result)20 bool QuicDataReader::ReadUInt16(uint16* result) {
21   return ReadBytes(result, sizeof(*result));
22 }
23 
ReadUInt32(uint32 * result)24 bool QuicDataReader::ReadUInt32(uint32* result) {
25   return ReadBytes(result, sizeof(*result));
26 }
27 
ReadUInt48(uint64 * result)28 bool QuicDataReader::ReadUInt48(uint64* result) {
29   uint32 lo;
30   if (!ReadUInt32(&lo)) {
31     return false;
32   }
33 
34   uint16 hi;
35   if (!ReadUInt16(&hi)) {
36     return false;
37   }
38 
39   *result = hi;
40   *result <<= 32;
41   *result += lo;
42 
43   return true;
44 }
45 
ReadUInt64(uint64 * result)46 bool QuicDataReader::ReadUInt64(uint64* result) {
47   return ReadBytes(result, sizeof(*result));
48 }
49 
ReadUInt128(uint128 * result)50 bool QuicDataReader::ReadUInt128(uint128* result) {
51   uint64 high_hash;
52   uint64 low_hash;
53 
54   if (!ReadUInt64(&low_hash)) {
55     return false;
56   }
57   if (!ReadUInt64(&high_hash)) {
58     return false;
59   }
60 
61   *result = uint128(high_hash, low_hash);
62   return true;
63 }
64 
ReadUFloat16(uint64 * result)65 bool QuicDataReader::ReadUFloat16(uint64* result) {
66   uint16 value;
67   if (!ReadUInt16(&value)) {
68     return false;
69   }
70 
71   *result = value;
72   if (*result < (1 << kUFloat16MantissaEffectiveBits)) {
73     // Fast path: either the value is denormalized (no hidden bit), or
74     // normalized (hidden bit set, exponent offset by one) with exponent zero.
75     // Zero exponent offset by one sets the bit exactly where the hidden bit is.
76     // So in both cases the value encodes itself.
77     return true;
78   }
79 
80   uint16 exponent = value >> kUFloat16MantissaBits;  // No sign extend on uint!
81   // After the fast pass, the exponent is at least one (offset by one).
82   // Un-offset the exponent.
83   --exponent;
84   DCHECK_GE(exponent, 1);
85   DCHECK_LE(exponent, kUFloat16MaxExponent);
86   // Here we need to clear the exponent and set the hidden bit. We have already
87   // decremented the exponent, so when we subtract it, it leaves behind the
88   // hidden bit.
89   *result -= exponent << kUFloat16MantissaBits;
90   *result <<= exponent;
91   DCHECK_GE(value, 1 << kUFloat16MantissaEffectiveBits);
92   DCHECK_LE(value, kUFloat16MaxValue);
93   return true;
94 }
95 
ReadStringPiece16(StringPiece * result)96 bool QuicDataReader::ReadStringPiece16(StringPiece* result) {
97   // Read resultant length.
98   uint16 result_len;
99   if (!ReadUInt16(&result_len)) {
100     // OnFailure() already called.
101     return false;
102   }
103 
104   return ReadStringPiece(result, result_len);
105 }
106 
ReadStringPiece(StringPiece * result,size_t size)107 bool QuicDataReader::ReadStringPiece(StringPiece* result, size_t size) {
108   // Make sure that we have enough data to read.
109   if (!CanRead(size)) {
110     OnFailure();
111     return false;
112   }
113 
114   // Set result.
115   result->set(data_ + pos_, size);
116 
117   // Iterate.
118   pos_ += size;
119 
120   return true;
121 }
122 
ReadRemainingPayload()123 StringPiece QuicDataReader::ReadRemainingPayload() {
124   StringPiece payload = PeekRemainingPayload();
125   pos_ = len_;
126   return payload;
127 }
128 
PeekRemainingPayload()129 StringPiece QuicDataReader::PeekRemainingPayload() {
130   return StringPiece(data_ + pos_, len_ - pos_);
131 }
132 
ReadBytes(void * result,size_t size)133 bool QuicDataReader::ReadBytes(void* result, size_t size) {
134   // Make sure that we have enough data to read.
135   if (!CanRead(size)) {
136     OnFailure();
137     return false;
138   }
139 
140   // Read into result.
141   memcpy(result, data_ + pos_, size);
142 
143   // Iterate.
144   pos_ += size;
145 
146   return true;
147 }
148 
IsDoneReading() const149 bool QuicDataReader::IsDoneReading() const {
150   return len_ == pos_;
151 }
152 
BytesRemaining() const153 size_t QuicDataReader::BytesRemaining() const {
154   return len_ - pos_;
155 }
156 
CanRead(size_t bytes) const157 bool QuicDataReader::CanRead(size_t bytes) const {
158   return bytes <= (len_ - pos_);
159 }
160 
OnFailure()161 void QuicDataReader::OnFailure() {
162   // Set our iterator to the end of the buffer so that further reads fail
163   // immediately.
164   pos_ = len_;
165 }
166 
167 }  // namespace net
168