| Index: net/spdy/spdy_protocol.h
 | 
| diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h
 | 
| index 0647ea15b42fa9081b485d69a69586fe096b0033..e9faa24d445c40665f2be67617d8a329441c80a3 100644
 | 
| --- a/net/spdy/spdy_protocol.h
 | 
| +++ b/net/spdy/spdy_protocol.h
 | 
| @@ -8,9 +8,12 @@
 | 
|  #define NET_SPDY_SPDY_PROTOCOL_H_
 | 
|  
 | 
|  #include <limits>
 | 
| +#include <map>
 | 
| +#include <vector>
 | 
|  
 | 
|  #include "base/basictypes.h"
 | 
|  #include "base/logging.h"
 | 
| +#include "base/string_piece.h"
 | 
|  #include "base/sys_byteorder.h"
 | 
|  #include "net/spdy/spdy_bitmasks.h"
 | 
|  
 | 
| @@ -355,6 +358,7 @@ const int kV3DictionarySize = arraysize(kV3Dictionary);
 | 
|  // Note: all protocol data structures are on-the-wire format.  That means that
 | 
|  //       data is stored in network-normalized order.  Readers must use the
 | 
|  //       accessors provided or call ntohX() functions.
 | 
| +// TODO(hkhalil): remove above note.
 | 
|  
 | 
|  // Types of Spdy Control Frames.
 | 
|  enum SpdyControlType {
 | 
| @@ -445,6 +449,12 @@ typedef uint32 SpdyStreamId;
 | 
|  // number between 0 and 3.
 | 
|  typedef uint8 SpdyPriority;
 | 
|  
 | 
| +typedef uint8 SpdyCredentialSlot;
 | 
| +
 | 
| +typedef std::map<std::string, std::string> SpdyNameValueBlock;
 | 
| +
 | 
| +typedef uint32 SpdyPingId;
 | 
| +
 | 
|  // -------------------------------------------------------------------------
 | 
|  // These structures mirror the protocol structure definitions.
 | 
|  
 | 
| @@ -532,6 +542,298 @@ struct SpdyWindowUpdateControlFrameBlock : SpdyFrameBlock {
 | 
|  
 | 
|  #pragma pack(pop)
 | 
|  
 | 
| +class SpdyFrame;
 | 
| +typedef SpdyFrame SpdySerializedFrame;
 | 
| +
 | 
| +class SpdyFramer;
 | 
| +class SpdyFrameBuilder;
 | 
| +
 | 
| +// Intermediate representation for SPDY frames.
 | 
| +// TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is
 | 
| +// gone.
 | 
| +class SpdyFrameIR {
 | 
| + public:
 | 
| +  virtual ~SpdyFrameIR() {}
 | 
| +
 | 
| + protected:
 | 
| +  SpdyFrameIR() {}
 | 
| +
 | 
| + private:
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyFrameIR);
 | 
| +};
 | 
| +
 | 
| +// Abstract class intended to be inherited by IRs that have a stream associated
 | 
| +// to them.
 | 
| +class SpdyFrameWithStreamIdIR : public SpdyFrameIR {
 | 
| + public:
 | 
| +  virtual ~SpdyFrameWithStreamIdIR() {}
 | 
| +  SpdyStreamId stream_id() const { return stream_id_; }
 | 
| +  void set_stream_id(SpdyStreamId stream_id) {
 | 
| +    // TODO(hkhalil): DCHECK_LT(0u, stream_id);
 | 
| +    DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
 | 
| +    stream_id_ = stream_id;
 | 
| +  }
 | 
| +
 | 
| + protected:
 | 
| +  explicit SpdyFrameWithStreamIdIR(SpdyStreamId stream_id) {
 | 
| +    set_stream_id(stream_id);
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  SpdyStreamId stream_id_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithStreamIdIR);
 | 
| +};
 | 
| +
 | 
| +// Abstract class intended to be inherited by IRs that have the option of a FIN
 | 
| +// flag. Implies SpdyFrameWithStreamIdIR.
 | 
| +class SpdyFrameWithFinIR : public SpdyFrameWithStreamIdIR {
 | 
| + public:
 | 
| +  virtual ~SpdyFrameWithFinIR() {}
 | 
| +  bool fin() const { return fin_; }
 | 
| +  void set_fin(bool fin) { fin_ = fin; }
 | 
| +
 | 
| + protected:
 | 
| +  explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
 | 
| +      : SpdyFrameWithStreamIdIR(stream_id),
 | 
| +        fin_(false) {}
 | 
| +
 | 
| + private:
 | 
| +  bool fin_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithFinIR);
 | 
| +};
 | 
| +
 | 
| +// Abstract class intended to be inherited by IRs that contain a name-value
 | 
| +// block. Implies SpdyFrameWithFinIR.
 | 
| +class SpdyFrameWithNameValueBlockIR : public SpdyFrameWithFinIR {
 | 
| + public:
 | 
| +  const SpdyNameValueBlock& name_value_block() const {
 | 
| +    return name_value_block_;
 | 
| +  }
 | 
| +  SpdyNameValueBlock* GetMutableNameValueBlock() { return &name_value_block_; }
 | 
| +
 | 
| + protected:
 | 
| +  explicit SpdyFrameWithNameValueBlockIR(SpdyStreamId stream_id);
 | 
| +  virtual ~SpdyFrameWithNameValueBlockIR();
 | 
| +
 | 
| + private:
 | 
| +  SpdyNameValueBlock name_value_block_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyFrameWithNameValueBlockIR);
 | 
| +};
 | 
| +
 | 
| +class SpdyDataIR : public SpdyFrameWithFinIR {
 | 
| + public:
 | 
| +  SpdyDataIR(SpdyStreamId stream_id, const base::StringPiece& data)
 | 
| +      : SpdyFrameWithFinIR(stream_id) {
 | 
| +    set_data(data);
 | 
| +  }
 | 
| +  base::StringPiece data() const { return data_; }
 | 
| +  void set_data(const base::StringPiece& data) { data.CopyToString(&data_); }
 | 
| +
 | 
| + private:
 | 
| +  std::string data_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyDataIR);
 | 
| +};
 | 
| +
 | 
| +class SpdySynStreamIR : public SpdyFrameWithNameValueBlockIR {
 | 
| + public:
 | 
| +  explicit SpdySynStreamIR(SpdyStreamId stream_id)
 | 
| +      : SpdyFrameWithNameValueBlockIR(stream_id),
 | 
| +        associated_to_stream_id_(0),
 | 
| +        priority_(0),
 | 
| +        slot_(0),
 | 
| +        unidirectional_(false) {}
 | 
| +  SpdyStreamId associated_to_stream_id() const {
 | 
| +    return associated_to_stream_id_;
 | 
| +  }
 | 
| +  void set_associated_to_stream_id(SpdyStreamId stream_id) {
 | 
| +    associated_to_stream_id_ = stream_id;
 | 
| +  }
 | 
| +  SpdyPriority priority() const { return priority_; }
 | 
| +  void set_priority(SpdyPriority priority) { priority_ = priority; }
 | 
| +  SpdyCredentialSlot slot() const { return slot_; }
 | 
| +  void set_slot(SpdyCredentialSlot slot) { slot_ = slot; }
 | 
| +  bool unidirectional() const { return unidirectional_; }
 | 
| +  void set_unidirectional(bool unidirectional) {
 | 
| +    unidirectional_ = unidirectional;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  SpdyStreamId associated_to_stream_id_;
 | 
| +  SpdyPriority priority_;
 | 
| +  SpdyCredentialSlot slot_;
 | 
| +  bool unidirectional_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdySynStreamIR);
 | 
| +};
 | 
| +
 | 
| +class SpdySynReplyIR : public SpdyFrameWithNameValueBlockIR {
 | 
| + public:
 | 
| +  explicit SpdySynReplyIR(SpdyStreamId stream_id)
 | 
| +      : SpdyFrameWithNameValueBlockIR(stream_id) {}
 | 
| +
 | 
| + private:
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdySynReplyIR);
 | 
| +};
 | 
| +
 | 
| +class SpdyRstStreamIR : public SpdyFrameWithStreamIdIR {
 | 
| + public:
 | 
| +  SpdyRstStreamIR(SpdyStreamId stream_id, SpdyRstStreamStatus status)
 | 
| +      : SpdyFrameWithStreamIdIR(stream_id) {
 | 
| +    set_status(status);
 | 
| +  }
 | 
| +  SpdyRstStreamStatus status() const {
 | 
| +    return status_;
 | 
| +  }
 | 
| +  void set_status(SpdyRstStreamStatus status) {
 | 
| +    DCHECK_NE(status, RST_STREAM_INVALID);
 | 
| +    DCHECK_LT(status, RST_STREAM_NUM_STATUS_CODES);
 | 
| +    status_ = status;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  SpdyRstStreamStatus status_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyRstStreamIR);
 | 
| +};
 | 
| +
 | 
| +class SpdySettingsIR : public SpdyFrameIR {
 | 
| + public:
 | 
| +  // Associates flags with a value.
 | 
| +  struct Value {
 | 
| +    Value() : persist_value(false),
 | 
| +              persisted(false),
 | 
| +              value(0) {}
 | 
| +    bool persist_value;
 | 
| +    bool persisted;
 | 
| +    int32 value;
 | 
| +  };
 | 
| +  typedef std::map<SpdySettingsIds, Value> ValueMap;
 | 
| +
 | 
| +  SpdySettingsIR();
 | 
| +
 | 
| +  virtual ~SpdySettingsIR();
 | 
| +
 | 
| +  // Overwrites as appropriate.
 | 
| +  const ValueMap& values() const { return values_; }
 | 
| +  void AddSetting(SpdySettingsIds id,
 | 
| +                  bool persist_value,
 | 
| +                  bool persisted,
 | 
| +                  int32 value) {
 | 
| +    // TODO(hkhalil): DCHECK_LE(SETTINGS_UPLOAD_BANDWIDTH, id);
 | 
| +    // TODO(hkhalil): DCHECK_GE(SETTINGS_INITIAL_WINDOW_SIZE, id);
 | 
| +    values_[id].persist_value = persist_value;
 | 
| +    values_[id].persisted = persisted;
 | 
| +    values_[id].value = value;
 | 
| +  }
 | 
| +  bool clear_settings() const { return clear_settings_; }
 | 
| +  void set_clear_settings(bool clear_settings) {
 | 
| +    clear_settings_ = clear_settings;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  ValueMap values_;
 | 
| +  bool clear_settings_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdySettingsIR);
 | 
| +};
 | 
| +
 | 
| +class SpdyPingIR : public SpdyFrameIR {
 | 
| + public:
 | 
| +  explicit SpdyPingIR(SpdyPingId id) : id_(id) {}
 | 
| +  SpdyPingId id() const { return id_; }
 | 
| +
 | 
| + private:
 | 
| +  SpdyPingId id_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyPingIR);
 | 
| +};
 | 
| +
 | 
| +class SpdyGoAwayIR : public SpdyFrameIR {
 | 
| + public:
 | 
| +  SpdyGoAwayIR(SpdyStreamId last_good_stream_id, SpdyGoAwayStatus status) {
 | 
| +    set_last_good_stream_id(last_good_stream_id);
 | 
| +    set_status(status);
 | 
| +  }
 | 
| +  SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
 | 
| +  void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
 | 
| +    DCHECK_LE(0u, last_good_stream_id);
 | 
| +    DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
 | 
| +    last_good_stream_id_ = last_good_stream_id;
 | 
| +  }
 | 
| +  SpdyGoAwayStatus status() const { return status_; }
 | 
| +  void set_status(SpdyGoAwayStatus status) {
 | 
| +    // TODO(hkhalil): Check valid ranges of status?
 | 
| +    status_ = status;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  SpdyStreamId last_good_stream_id_;
 | 
| +  SpdyGoAwayStatus status_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyGoAwayIR);
 | 
| +};
 | 
| +
 | 
| +class SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR {
 | 
| + public:
 | 
| +  explicit SpdyHeadersIR(SpdyStreamId stream_id)
 | 
| +      : SpdyFrameWithNameValueBlockIR(stream_id) {}
 | 
| +
 | 
| + private:
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR);
 | 
| +};
 | 
| +
 | 
| +class SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR {
 | 
| + public:
 | 
| +  SpdyWindowUpdateIR(SpdyStreamId stream_id, int32 delta)
 | 
| +      : SpdyFrameWithStreamIdIR(stream_id) {
 | 
| +    set_delta(delta);
 | 
| +  }
 | 
| +  int32 delta() const { return delta_; }
 | 
| +  void set_delta(int32 delta) {
 | 
| +    DCHECK_LT(0, delta);
 | 
| +    DCHECK_LE(delta, kSpdyStreamMaximumWindowSize);
 | 
| +    delta_ = delta;
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  int32 delta_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyWindowUpdateIR);
 | 
| +};
 | 
| +
 | 
| +class SpdyCredentialIR : public SpdyFrameIR {
 | 
| + public:
 | 
| +  typedef std::vector<std::string> CertificateList;
 | 
| +
 | 
| +  explicit SpdyCredentialIR(int16 slot);
 | 
| +  virtual ~SpdyCredentialIR();
 | 
| +
 | 
| +  int16 slot() const { return slot_; }
 | 
| +  void set_slot(int16 slot) {
 | 
| +    // TODO(hkhalil): Verify valid slot range?
 | 
| +    slot_ = slot;
 | 
| +  }
 | 
| +  base::StringPiece proof() const { return proof_; }
 | 
| +  void set_proof(const base::StringPiece& proof) {
 | 
| +    proof.CopyToString(&proof_);
 | 
| +  }
 | 
| +  const CertificateList* certificates() const { return &certificates_; }
 | 
| +  void AddCertificate(const base::StringPiece& certificate) {
 | 
| +    certificates_.push_back(certificate.as_string());
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  int16 slot_;
 | 
| +  std::string proof_;
 | 
| +  CertificateList certificates_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(SpdyCredentialIR);
 | 
| +};
 | 
| +
 | 
|  // -------------------------------------------------------------------------
 | 
|  // Wrapper classes for various SPDY frames.
 | 
|  
 | 
| @@ -731,7 +1033,7 @@ class SpdySynStreamControlFrame : public SpdyControlFrame {
 | 
|    }
 | 
|  
 | 
|    void set_credential_slot(uint8 credential_slot) {
 | 
| -    DCHECK(version() >= 3);
 | 
| +    DCHECK_LE(3, version());
 | 
|      mutable_block()->credential_slot_ = credential_slot;
 | 
|    }
 | 
|  
 | 
| 
 |