15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_data_reader.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/int128.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/quic_protocol.h"
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicDataReader::QuicDataReader(const char* data, const size_t len)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : data_(data),
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      len_(len),
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pos_(0) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::ReadUInt16(uint16* result) {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ReadBytes(result, sizeof(*result));
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::ReadUInt32(uint32* result) {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ReadBytes(result, sizeof(*result));
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::ReadUInt48(uint64* result) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 lo;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ReadUInt32(&lo)) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint16 hi;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ReadUInt16(&hi)) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = hi;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result <<= 32;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result += lo;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::ReadUInt64(uint64* result) {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ReadBytes(result, sizeof(*result));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::ReadUInt128(uint128* result) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 high_hash;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 low_hash;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ReadUInt64(&low_hash)) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ReadUInt64(&high_hash)) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = uint128(high_hash, low_hash);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool QuicDataReader::ReadUFloat16(uint64* result) {
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint16 value;
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!ReadUInt16(&value)) {
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *result = value;
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (*result < (1 << kUFloat16MantissaEffectiveBits)) {
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Fast path: either the value is denormalized (no hidden bit), or
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // normalized (hidden bit set, exponent offset by one) with exponent zero.
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Zero exponent offset by one sets the bit exactly where the hidden bit is.
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // So in both cases the value encodes itself.
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return true;
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint16 exponent = value >> kUFloat16MantissaBits;  // No sign extend on uint!
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // After the fast pass, the exponent is at least one (offset by one).
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Un-offset the exponent.
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  --exponent;
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(exponent, 1);
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_LE(exponent, kUFloat16MaxExponent);
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Here we need to clear the exponent and set the hidden bit. We have already
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // decremented the exponent, so when we subtract it, it leaves behind the
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // hidden bit.
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *result -= exponent << kUFloat16MantissaBits;
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  *result <<= exponent;
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_GE(value, 1 << kUFloat16MantissaEffectiveBits);
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_LE(value, kUFloat16MaxValue);
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return true;
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::ReadStringPiece16(StringPiece* result) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read resultant length.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint16 result_len;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ReadUInt16(&result_len)) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnFailure() already called.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ReadStringPiece(result, result_len);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicDataReader::ReadStringPiece(StringPiece* result, size_t size) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that we have enough data to read.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanRead(size)) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnFailure();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set result.
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  result->set(data_ + pos_, size);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Iterate.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pos_ += size;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StringPiece QuicDataReader::ReadRemainingPayload() {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringPiece payload = PeekRemainingPayload();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pos_ = len_;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return payload;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StringPiece QuicDataReader::PeekRemainingPayload() {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return StringPiece(data_ + pos_, len_ - pos_);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool QuicDataReader::ReadBytes(void* result, size_t size) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that we have enough data to read.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanRead(size)) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnFailure();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Read into result.
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memcpy(result, data_ + pos_, size);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Iterate.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pos_ += size;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::IsDoneReading() const {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return len_ == pos_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t QuicDataReader::BytesRemaining() const {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return len_ - pos_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuicDataReader::CanRead(size_t bytes) const {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes <= (len_ - pos_);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuicDataReader::OnFailure() {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set our iterator to the end of the buffer so that further reads fail
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // immediately.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pos_ = len_;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
168