Home | History | Annotate | Download | only in spdy
      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 <limits>
      6 
      7 #include "base/sys_byteorder.h"
      8 #include "net/spdy/spdy_frame_reader.h"
      9 #include "net/spdy/spdy_protocol.h"
     10 
     11 namespace net {
     12 
     13 SpdyFrameReader::SpdyFrameReader(const char* data, const size_t len)
     14     : data_(data),
     15       len_(len),
     16       ofs_(0) {
     17 }
     18 
     19 bool SpdyFrameReader::ReadUInt8(uint8* result) {
     20   // Make sure that we have the whole uint8.
     21   if (!CanRead(1)) {
     22     OnFailure();
     23     return false;
     24   }
     25 
     26   // Read into result.
     27   *result = *reinterpret_cast<const uint8*>(data_ + ofs_);
     28 
     29   // Iterate.
     30   ofs_ += 1;
     31 
     32   return true;
     33 }
     34 
     35 bool SpdyFrameReader::ReadUInt16(uint16* result) {
     36   // Make sure that we have the whole uint16.
     37   if (!CanRead(2)) {
     38     OnFailure();
     39     return false;
     40   }
     41 
     42   // Read into result.
     43   *result = ntohs(*(reinterpret_cast<const uint16*>(data_ + ofs_)));
     44 
     45   // Iterate.
     46   ofs_ += 2;
     47 
     48   return true;
     49 }
     50 
     51 bool SpdyFrameReader::ReadUInt32(uint32* result) {
     52   // Make sure that we have the whole uint32.
     53   if (!CanRead(4)) {
     54     OnFailure();
     55     return false;
     56   }
     57 
     58   // Read into result.
     59   *result = ntohl(*(reinterpret_cast<const uint32*>(data_ + ofs_)));
     60 
     61   // Iterate.
     62   ofs_ += 4;
     63 
     64   return true;
     65 }
     66 
     67 bool SpdyFrameReader::ReadUInt31(uint32* result) {
     68   bool success = ReadUInt32(result);
     69 
     70   // Zero out highest-order bit.
     71   if (success) {
     72     *result &= 0x7fffffff;
     73   }
     74 
     75   return success;
     76 }
     77 
     78 bool SpdyFrameReader::ReadUInt24(uint32* result) {
     79   // Make sure that we have the whole uint24.
     80   if (!CanRead(3)) {
     81     OnFailure();
     82     return false;
     83   }
     84 
     85   // Read into result.
     86   *result = 0;
     87   memcpy(reinterpret_cast<char*>(result) + 1, data_ + ofs_, 3);
     88   *result = ntohl(*result);
     89 
     90   // Iterate.
     91   ofs_ += 3;
     92 
     93   return true;
     94 }
     95 
     96 bool SpdyFrameReader::ReadStringPiece16(base::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   // Make sure that we have the whole string.
    105   if (!CanRead(result_len)) {
    106     OnFailure();
    107     return false;
    108   }
    109 
    110   // Set result.
    111   result->set(data_ + ofs_, result_len);
    112 
    113   // Iterate.
    114   ofs_ += result_len;
    115 
    116   return true;
    117 }
    118 
    119 bool SpdyFrameReader::ReadStringPiece32(base::StringPiece* result) {
    120   // Read resultant length.
    121   uint32 result_len;
    122   if (!ReadUInt32(&result_len)) {
    123     // OnFailure() already called.
    124     return false;
    125   }
    126 
    127   // Make sure that we have the whole string.
    128   if (!CanRead(result_len)) {
    129     OnFailure();
    130     return false;
    131   }
    132 
    133   // Set result.
    134   result->set(data_ + ofs_, result_len);
    135 
    136   // Iterate.
    137   ofs_ += result_len;
    138 
    139   return true;
    140 }
    141 
    142 bool SpdyFrameReader::ReadBytes(void* result, size_t size) {
    143   // Make sure that we have enough data to read.
    144   if (!CanRead(size)) {
    145     OnFailure();
    146     return false;
    147   }
    148 
    149   // Read into result.
    150   memcpy(result, data_ + ofs_, size);
    151 
    152   // Iterate.
    153   ofs_ += size;
    154 
    155   return true;
    156 }
    157 
    158 bool SpdyFrameReader::Seek(size_t size) {
    159   if (!CanRead(size)) {
    160     OnFailure();
    161     return false;
    162   }
    163 
    164   // Iterate.
    165   ofs_ += size;
    166 
    167   return true;
    168 }
    169 
    170 bool SpdyFrameReader::IsDoneReading() const {
    171   return len_ == ofs_;
    172 }
    173 
    174 bool SpdyFrameReader::CanRead(size_t bytes) const {
    175   return bytes <= (len_ - ofs_);
    176 }
    177 
    178 void SpdyFrameReader::OnFailure() {
    179   // Set our iterator to the end of the buffer so that further reads fail
    180   // immediately.
    181   ofs_ = len_;
    182 }
    183 
    184 }  // namespace net
    185