// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/spdy/hpack_header_table.h" #include "base/logging.h" #include "net/spdy/hpack_string_util.h" namespace net { HpackHeaderTable::HpackHeaderTable() : size_(0), max_size_(4096) {} HpackHeaderTable::~HpackHeaderTable() {} uint32 HpackHeaderTable::GetEntryCount() const { size_t size = entries_.size(); DCHECK_LE(size, kuint32max); return static_cast(size); } const HpackEntry& HpackHeaderTable::GetEntry(uint32 index) const { CHECK_LT(index, GetEntryCount()); return entries_[index]; } HpackEntry* HpackHeaderTable::GetMutableEntry(uint32 index) { CHECK_LT(index, GetEntryCount()); return &entries_[index]; } void HpackHeaderTable::SetMaxSize(uint32 max_size) { max_size_ = max_size; while (size_ > max_size_) { CHECK(!entries_.empty()); size_ -= entries_.back().Size(); entries_.pop_back(); } } void HpackHeaderTable::TryAddEntry( const HpackEntry& entry, int32* index, std::vector* removed_referenced_indices) { *index = -1; removed_referenced_indices->clear(); // The algorithm used here is described in 3.3.3. We're assuming // that the given entry is caching the name/value. size_t target_size = 0; size_t size_t_max_size = static_cast(max_size_); if (entry.Size() <= size_t_max_size) { // The conditional implies the difference can fit in 32 bits. target_size = size_t_max_size - entry.Size(); } while ((static_cast(size_) > target_size) && !entries_.empty()) { if (entries_.back().IsReferenced()) { removed_referenced_indices->push_back(entries_.size() - 1); } size_ -= entries_.back().Size(); entries_.pop_back(); } if (entry.Size() <= size_t_max_size) { // Implied by the exit condition of the while loop above and the // condition of the if. DCHECK_LE(static_cast(size_) + entry.Size(), size_t_max_size); size_ += entry.Size(); *index = 0; entries_.push_front(entry); } } } // namespace net