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 using base::StringPiece; 8 9 namespace net { 10 11 QuicDataReader::QuicDataReader(const char* data, const size_t len) 12 : data_(data), 13 len_(len), 14 pos_(0) { 15 } 16 17 bool QuicDataReader::ReadUInt16(uint16* result) { 18 return ReadBytes(result, sizeof(*result)); 19 } 20 21 bool QuicDataReader::ReadUInt32(uint32* result) { 22 return ReadBytes(result, sizeof(*result)); 23 } 24 25 bool QuicDataReader::ReadUInt48(uint64* result) { 26 uint32 lo; 27 if (!ReadUInt32(&lo)) { 28 return false; 29 } 30 31 uint16 hi; 32 if (!ReadUInt16(&hi)) { 33 return false; 34 } 35 36 *result = hi; 37 *result <<= 32; 38 *result += lo; 39 40 return true; 41 } 42 43 bool QuicDataReader::ReadUInt64(uint64* result) { 44 return ReadBytes(result, sizeof(*result)); 45 } 46 47 bool QuicDataReader::ReadUInt128(uint128* result) { 48 uint64 high_hash; 49 uint64 low_hash; 50 51 if (!ReadUInt64(&low_hash)) { 52 return false; 53 } 54 if (!ReadUInt64(&high_hash)) { 55 return false; 56 } 57 58 *result = uint128(high_hash, low_hash); 59 return true; 60 } 61 62 bool QuicDataReader::ReadStringPiece16(StringPiece* result) { 63 // Read resultant length. 64 uint16 result_len; 65 if (!ReadUInt16(&result_len)) { 66 // OnFailure() already called. 67 return false; 68 } 69 70 return ReadStringPiece(result, result_len); 71 } 72 73 bool QuicDataReader::ReadStringPiece(StringPiece* result, size_t size) { 74 // Make sure that we have enough data to read. 75 if (!CanRead(size)) { 76 OnFailure(); 77 return false; 78 } 79 80 // Set result. 81 result->set(data_ + pos_, size); 82 83 // Iterate. 84 pos_ += size; 85 86 return true; 87 } 88 89 StringPiece QuicDataReader::ReadRemainingPayload() { 90 StringPiece payload = PeekRemainingPayload(); 91 pos_ = len_; 92 return payload; 93 } 94 95 StringPiece QuicDataReader::PeekRemainingPayload() { 96 return StringPiece(data_ + pos_, len_ - pos_); 97 } 98 99 bool QuicDataReader::ReadBytes(void* result, size_t size) { 100 // Make sure that we have enough data to read. 101 if (!CanRead(size)) { 102 OnFailure(); 103 return false; 104 } 105 106 // Read into result. 107 memcpy(result, data_ + pos_, size); 108 109 // Iterate. 110 pos_ += size; 111 112 return true; 113 } 114 115 bool QuicDataReader::IsDoneReading() const { 116 return len_ == pos_; 117 } 118 119 size_t QuicDataReader::BytesRemaining() const { 120 return len_ - pos_; 121 } 122 123 bool QuicDataReader::CanRead(size_t bytes) const { 124 return bytes <= (len_ - pos_); 125 } 126 127 void QuicDataReader::OnFailure() { 128 // Set our iterator to the end of the buffer so that further reads fail 129 // immediately. 130 pos_ = len_; 131 } 132 133 } // namespace net 134