Deletes classes in //third_party/spdy/core that are only referenced by unit tests. Protected by deleting unused code; not protected. PiperOrigin-RevId: 596095895
diff --git a/build/source_list.bzl b/build/source_list.bzl index bd02a2f..fd8192c 100644 --- a/build/source_list.bzl +++ b/build/source_list.bzl
@@ -387,10 +387,7 @@ "spdy/core/spdy_frame_builder.h", "spdy/core/spdy_framer.h", "spdy/core/spdy_headers_handler_interface.h", - "spdy/core/spdy_intrusive_list.h", "spdy/core/spdy_no_op_visitor.h", - "spdy/core/spdy_pinnable_buffer_piece.h", - "spdy/core/spdy_prefixed_buffer_reader.h", "spdy/core/spdy_protocol.h", "spdy/core/zero_copy_output_buffer.h", "web_transport/complete_buffer_visitor.h", @@ -682,8 +679,6 @@ "spdy/core/spdy_frame_builder.cc", "spdy/core/spdy_framer.cc", "spdy/core/spdy_no_op_visitor.cc", - "spdy/core/spdy_pinnable_buffer_piece.cc", - "spdy/core/spdy_prefixed_buffer_reader.cc", "spdy/core/spdy_protocol.cc", "web_transport/complete_buffer_visitor.cc", "web_transport/encapsulated/encapsulated_web_transport.cc", @@ -1313,9 +1308,6 @@ "spdy/core/spdy_alt_svc_wire_format_test.cc", "spdy/core/spdy_frame_builder_test.cc", "spdy/core/spdy_framer_test.cc", - "spdy/core/spdy_intrusive_list_test.cc", - "spdy/core/spdy_pinnable_buffer_piece_test.cc", - "spdy/core/spdy_prefixed_buffer_reader_test.cc", "spdy/core/spdy_protocol_test.cc", "web_transport/encapsulated/encapsulated_web_transport_test.cc", "web_transport/web_transport_headers_test.cc",
diff --git a/build/source_list.gni b/build/source_list.gni index 49ae31f..d3fb7a0 100644 --- a/build/source_list.gni +++ b/build/source_list.gni
@@ -387,10 +387,7 @@ "src/quiche/spdy/core/spdy_frame_builder.h", "src/quiche/spdy/core/spdy_framer.h", "src/quiche/spdy/core/spdy_headers_handler_interface.h", - "src/quiche/spdy/core/spdy_intrusive_list.h", "src/quiche/spdy/core/spdy_no_op_visitor.h", - "src/quiche/spdy/core/spdy_pinnable_buffer_piece.h", - "src/quiche/spdy/core/spdy_prefixed_buffer_reader.h", "src/quiche/spdy/core/spdy_protocol.h", "src/quiche/spdy/core/zero_copy_output_buffer.h", "src/quiche/web_transport/complete_buffer_visitor.h", @@ -682,8 +679,6 @@ "src/quiche/spdy/core/spdy_frame_builder.cc", "src/quiche/spdy/core/spdy_framer.cc", "src/quiche/spdy/core/spdy_no_op_visitor.cc", - "src/quiche/spdy/core/spdy_pinnable_buffer_piece.cc", - "src/quiche/spdy/core/spdy_prefixed_buffer_reader.cc", "src/quiche/spdy/core/spdy_protocol.cc", "src/quiche/web_transport/complete_buffer_visitor.cc", "src/quiche/web_transport/encapsulated/encapsulated_web_transport.cc", @@ -1314,9 +1309,6 @@ "src/quiche/spdy/core/spdy_alt_svc_wire_format_test.cc", "src/quiche/spdy/core/spdy_frame_builder_test.cc", "src/quiche/spdy/core/spdy_framer_test.cc", - "src/quiche/spdy/core/spdy_intrusive_list_test.cc", - "src/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc", - "src/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc", "src/quiche/spdy/core/spdy_protocol_test.cc", "src/quiche/web_transport/encapsulated/encapsulated_web_transport_test.cc", "src/quiche/web_transport/web_transport_headers_test.cc",
diff --git a/build/source_list.json b/build/source_list.json index 252c803..69eeccd 100644 --- a/build/source_list.json +++ b/build/source_list.json
@@ -386,10 +386,7 @@ "quiche/spdy/core/spdy_frame_builder.h", "quiche/spdy/core/spdy_framer.h", "quiche/spdy/core/spdy_headers_handler_interface.h", - "quiche/spdy/core/spdy_intrusive_list.h", "quiche/spdy/core/spdy_no_op_visitor.h", - "quiche/spdy/core/spdy_pinnable_buffer_piece.h", - "quiche/spdy/core/spdy_prefixed_buffer_reader.h", "quiche/spdy/core/spdy_protocol.h", "quiche/spdy/core/zero_copy_output_buffer.h", "quiche/web_transport/complete_buffer_visitor.h", @@ -681,8 +678,6 @@ "quiche/spdy/core/spdy_frame_builder.cc", "quiche/spdy/core/spdy_framer.cc", "quiche/spdy/core/spdy_no_op_visitor.cc", - "quiche/spdy/core/spdy_pinnable_buffer_piece.cc", - "quiche/spdy/core/spdy_prefixed_buffer_reader.cc", "quiche/spdy/core/spdy_protocol.cc", "quiche/web_transport/complete_buffer_visitor.cc", "quiche/web_transport/encapsulated/encapsulated_web_transport.cc", @@ -1313,9 +1308,6 @@ "quiche/spdy/core/spdy_alt_svc_wire_format_test.cc", "quiche/spdy/core/spdy_frame_builder_test.cc", "quiche/spdy/core/spdy_framer_test.cc", - "quiche/spdy/core/spdy_intrusive_list_test.cc", - "quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc", - "quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc", "quiche/spdy/core/spdy_protocol_test.cc", "quiche/web_transport/encapsulated/encapsulated_web_transport_test.cc", "quiche/web_transport/web_transport_headers_test.cc"
diff --git a/quiche/spdy/core/spdy_intrusive_list.h b/quiche/spdy/core/spdy_intrusive_list.h deleted file mode 100644 index 3ba8f8e..0000000 --- a/quiche/spdy/core/spdy_intrusive_list.h +++ /dev/null
@@ -1,342 +0,0 @@ -// Copyright (c) 2019 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. - -#ifndef QUICHE_SPDY_CORE_SPDY_INTRUSIVE_LIST_H_ -#define QUICHE_SPDY_CORE_SPDY_INTRUSIVE_LIST_H_ - -// A SpdyIntrusiveList<> is a doubly-linked list where the link pointers are -// embedded in the elements. They are circularly linked making insertion and -// removal into a known position constant time and branch-free operations. -// -// Usage is similar to an STL list<> where feasible, but there are important -// differences. First and foremost, the elements must derive from the -// SpdyIntrusiveLink<> base class: -// -// struct Foo : public SpdyIntrusiveLink<Foo> { -// // ... -// } -// -// SpdyIntrusiveList<Foo> l; -// l.push_back(new Foo); -// l.push_front(new Foo); -// l.erase(&l.front()); -// l.erase(&l.back()); -// -// Intrusive lists are primarily useful when you would have considered embedding -// link pointers in your class directly for space or performance reasons. An -// SpdyIntrusiveLink<> is the size of 2 pointers, usually 16 bytes on 64-bit -// systems. Intrusive lists do not perform memory allocation (unlike the STL -// list<> class) and thus may use less memory than list<>. In particular, if the -// list elements are pointers to objects, using a list<> would perform an extra -// memory allocation for each list node structure, while an SpdyIntrusiveList<> -// would not. -// -// Note that SpdyIntrusiveLink is exempt from the C++ style guide's limitations -// on multiple inheritance, so it's fine to inherit from both SpdyIntrusiveLink -// and a base class, even if the base class is not a pure interface. -// -// Because the list pointers are embedded in the objects stored in an -// SpdyIntrusiveList<>, erasing an item from a list is constant time. Consider -// the following: -// -// map<string,Foo> foo_map; -// list<Foo*> foo_list; -// -// foo_list.push_back(&foo_map["bar"]); -// foo_list.erase(&foo_map["bar"]); // Compile error! -// -// The problem here is that a Foo* doesn't know where on foo_list it resides, -// so removal requires iteration over the list. Various tricks can be performed -// to overcome this. For example, a foo_list::iterator can be stored inside of -// the Foo object. But at that point you'd be better off using an -// SpdyIntrusiveList<>: -// -// map<string,Foo> foo_map; -// SpdyIntrusiveList<Foo> foo_list; -// -// foo_list.push_back(&foo_map["bar"]); -// foo_list.erase(&foo_map["bar"]); // Yeah! -// -// Note that SpdyIntrusiveLists come with a few limitations. The primary -// limitation is that the SpdyIntrusiveLink<> base class is not copyable or -// assignable. The result is that STL algorithms which mutate the order of -// iterators, such as reverse() and unique(), will not work by default with -// SpdyIntrusiveLists. In order to allow these algorithms to work you'll need to -// define swap() and/or operator= for your class. -// -// Another limitation is that the SpdyIntrusiveList<> structure itself is not -// copyable or assignable since an item/link combination can only exist on one -// SpdyIntrusiveList<> at a time. This limitation is a result of the link -// pointers for an item being intrusive in the item itself. For example, the -// following will not compile: -// -// FooList a; -// FooList b(a); // no copy constructor -// b = a; // no assignment operator -// -// The similar STL code does work since the link pointers are external to the -// item: -// -// list<int*> a; -// a.push_back(new int); -// list<int*> b(a); -// QUICHE_CHECK(a.front() == b.front()); -// -// Note that SpdyIntrusiveList::size() runs in O(N) time. - -#include <stddef.h> - -#include <cstddef> -#include <iterator> - -#include "quiche/common/platform/api/quiche_export.h" - -namespace spdy { - -template <typename T, typename ListID> -class SpdyIntrusiveList; - -template <typename T, typename ListID = void> -class QUICHE_EXPORT SpdyIntrusiveLink { - protected: - // We declare the constructor protected so that only derived types and the - // befriended list can construct this. - SpdyIntrusiveLink() : next_(nullptr), prev_(nullptr) {} - -#ifndef SWIG - SpdyIntrusiveLink(const SpdyIntrusiveLink&) = delete; - SpdyIntrusiveLink& operator=(const SpdyIntrusiveLink&) = delete; -#endif // SWIG - - private: - // We befriend the matching list type so that it can manipulate the links - // while they are kept private from others. - friend class SpdyIntrusiveList<T, ListID>; - - // Encapsulates the logic to convert from a link to its derived type. - T* cast_to_derived() { return static_cast<T*>(this); } - const T* cast_to_derived() const { return static_cast<const T*>(this); } - - SpdyIntrusiveLink* next_; - SpdyIntrusiveLink* prev_; -}; - -template <typename T, typename ListID = void> -class QUICHE_EXPORT SpdyIntrusiveList { - template <typename QualifiedT, typename QualifiedLinkT> - class iterator_impl; - - public: - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - - typedef SpdyIntrusiveLink<T, ListID> link_type; - typedef iterator_impl<T, link_type> iterator; - typedef iterator_impl<const T, const link_type> const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - - SpdyIntrusiveList() { clear(); } - // After the move constructor the moved-from list will be empty. - // - // NOTE: There is no move assign operator (for now). - // The reason is that at the moment 'clear()' does not unlink the nodes. - // It makes is_linked() return true when it should return false. - // If such node is removed from the list (e.g. from its destructor), or is - // added to another list - a memory corruption will occur. - // Admitedly the destructor does not unlink the nodes either, but move-assign - // will likely make the problem more prominent. -#ifndef SWIG - SpdyIntrusiveList(SpdyIntrusiveList&& src) noexcept { - clear(); - if (src.empty()) return; - sentinel_link_.next_ = src.sentinel_link_.next_; - sentinel_link_.prev_ = src.sentinel_link_.prev_; - // Fix head and tail nodes of the list. - sentinel_link_.prev_->next_ = &sentinel_link_; - sentinel_link_.next_->prev_ = &sentinel_link_; - src.clear(); - } -#endif // SWIG - - iterator begin() { return iterator(sentinel_link_.next_); } - const_iterator begin() const { return const_iterator(sentinel_link_.next_); } - iterator end() { return iterator(&sentinel_link_); } - const_iterator end() const { return const_iterator(&sentinel_link_); } - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { - return const_reverse_iterator(begin()); - } - - bool empty() const { return (sentinel_link_.next_ == &sentinel_link_); } - // This runs in O(N) time. - size_type size() const { return std::distance(begin(), end()); } - size_type max_size() const { return size_type(-1); } - - reference front() { return *begin(); } - const_reference front() const { return *begin(); } - reference back() { return *(--end()); } - const_reference back() const { return *(--end()); } - - static iterator insert(iterator position, T* obj) { - return insert_link(position.link(), obj); - } - void push_front(T* obj) { insert(begin(), obj); } - void push_back(T* obj) { insert(end(), obj); } - - static iterator erase(T* obj) { - link_type* obj_link = obj; - // Fix up the next and previous links for the previous and next objects. - obj_link->next_->prev_ = obj_link->prev_; - obj_link->prev_->next_ = obj_link->next_; - // Zero out the next and previous links for the removed item. This will - // cause any future attempt to remove the item from the list to cause a - // crash instead of possibly corrupting the list structure. - link_type* next_link = obj_link->next_; - obj_link->next_ = nullptr; - obj_link->prev_ = nullptr; - return iterator(next_link); - } - - static iterator erase(iterator position) { - return erase(position.operator->()); - } - void pop_front() { erase(begin()); } - void pop_back() { erase(--end()); } - - // Check whether the given element is linked into some list. Note that this - // does *not* check whether it is linked into a particular list. - // Also, if clear() is used to clear the containing list, is_linked() will - // still return true even though obj is no longer in any list. - static bool is_linked(const T* obj) { - return obj->link_type::next_ != nullptr; - } - - void clear() { - sentinel_link_.next_ = sentinel_link_.prev_ = &sentinel_link_; - } - void swap(SpdyIntrusiveList& x) { - SpdyIntrusiveList tmp; - tmp.splice(tmp.begin(), *this); - this->splice(this->begin(), x); - x.splice(x.begin(), tmp); - } - - void splice(iterator pos, SpdyIntrusiveList& src) { - splice(pos, src.begin(), src.end()); - } - - void splice(iterator pos, iterator i) { splice(pos, i, std::next(i)); } - - void splice(iterator pos, iterator first, iterator last) { - if (first == last) return; - - link_type* const last_prev = last.link()->prev_; - - // Remove from the source. - first.link()->prev_->next_ = last.operator->(); - last.link()->prev_ = first.link()->prev_; - - // Attach to the destination. - first.link()->prev_ = pos.link()->prev_; - pos.link()->prev_->next_ = first.operator->(); - last_prev->next_ = pos.operator->(); - pos.link()->prev_ = last_prev; - } - - private: - static iterator insert_link(link_type* next_link, T* obj) { - link_type* obj_link = obj; - obj_link->next_ = next_link; - link_type* const initial_next_prev = next_link->prev_; - obj_link->prev_ = initial_next_prev; - initial_next_prev->next_ = obj_link; - next_link->prev_ = obj_link; - return iterator(obj_link); - } - - // The iterator implementation is parameterized on a potentially qualified - // variant of T and the matching qualified link type. Essentially, QualifiedT - // will either be 'T' or 'const T', the latter for a const_iterator. - template <typename QualifiedT, typename QualifiedLinkT> - class QUICHE_EXPORT iterator_impl { - public: - using iterator_category = std::bidirectional_iterator_tag; - using value_type = QualifiedT; - using difference_type = std::ptrdiff_t; - using pointer = QualifiedT*; - using reference = QualifiedT&; - - iterator_impl() = default; - iterator_impl(QualifiedLinkT* link) : link_(link) {} - iterator_impl(const iterator_impl& x) = default; - iterator_impl& operator=(const iterator_impl& x) = default; - - // Allow converting and comparing across iterators where the pointer - // assignment and comparisons (respectively) are allowed. - template <typename U, typename V> - iterator_impl(const iterator_impl<U, V>& x) : link_(x.link_) {} - template <typename U, typename V> - bool operator==(const iterator_impl<U, V>& x) const { - return link_ == x.link_; - } - template <typename U, typename V> - bool operator!=(const iterator_impl<U, V>& x) const { - return link_ != x.link_; - } - - reference operator*() const { return *operator->(); } - pointer operator->() const { return link_->cast_to_derived(); } - - QualifiedLinkT* link() const { return link_; } - -#ifndef SWIG // SWIG can't wrap these operator overloads. - iterator_impl& operator++() { - link_ = link_->next_; - return *this; - } - iterator_impl operator++(int /*unused*/) { - iterator_impl tmp = *this; - ++*this; - return tmp; - } - iterator_impl& operator--() { - link_ = link_->prev_; - return *this; - } - iterator_impl operator--(int /*unused*/) { - iterator_impl tmp = *this; - --*this; - return tmp; - } -#endif // SWIG - - private: - // Ensure iterators can access other iterators node directly. - template <typename U, typename V> - friend class iterator_impl; - - QualifiedLinkT* link_ = nullptr; - }; - - // This bare link acts as the sentinel node. - link_type sentinel_link_; - - // These are private and undefined to prevent copying and assigning. - SpdyIntrusiveList(const SpdyIntrusiveList&); - void operator=(const SpdyIntrusiveList&); -}; - -} // namespace spdy - -#endif // QUICHE_SPDY_CORE_SPDY_INTRUSIVE_LIST_H_
diff --git a/quiche/spdy/core/spdy_intrusive_list_test.cc b/quiche/spdy/core/spdy_intrusive_list_test.cc deleted file mode 100644 index 750608f..0000000 --- a/quiche/spdy/core/spdy_intrusive_list_test.cc +++ /dev/null
@@ -1,420 +0,0 @@ -// Copyright (c) 2019 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 "quiche/spdy/core/spdy_intrusive_list.h" - -#include <algorithm> -#include <iterator> -#include <list> -#include <string> -#include <utility> - -#include "quiche/common/platform/api/quiche_test.h" - -namespace spdy { -namespace test { - -struct ListId2 {}; - -struct TestItem : public SpdyIntrusiveLink<TestItem>, - public SpdyIntrusiveLink<TestItem, ListId2> { - int n; -}; -typedef SpdyIntrusiveList<TestItem> TestList; -typedef std::list<TestItem *> CanonicalList; - -void swap(TestItem &a, TestItem &b) { - using std::swap; - swap(a.n, b.n); -} - -class IntrusiveListTest : public quiche::test::QuicheTest { - protected: - void CheckLists() { - CheckLists(l1, ll1); - if (quiche::test::QuicheTest::HasFailure()) return; - CheckLists(l2, ll2); - } - - void CheckLists(const TestList &list_a, const CanonicalList &list_b) { - ASSERT_EQ(list_a.size(), list_b.size()); - TestList::const_iterator it_a = list_a.begin(); - CanonicalList::const_iterator it_b = list_b.begin(); - while (it_a != list_a.end()) { - EXPECT_EQ(&*it_a++, *it_b++); - } - EXPECT_EQ(list_a.end(), it_a); - EXPECT_EQ(list_b.end(), it_b); - } - - void PrepareLists(int num_elems_1, int num_elems_2 = 0) { - FillLists(&l1, &ll1, e, num_elems_1); - FillLists(&l2, &ll2, e + num_elems_1, num_elems_2); - } - - void FillLists(TestList *list_a, CanonicalList *list_b, TestItem *elems, - int num_elems) { - list_a->clear(); - list_b->clear(); - for (int i = 0; i < num_elems; ++i) { - list_a->push_back(elems + i); - list_b->push_back(elems + i); - } - CheckLists(*list_a, *list_b); - } - - TestItem e[10]; - TestList l1, l2; - CanonicalList ll1, ll2; -}; - -TEST(NewIntrusiveListTest, Basic) { - TestList list1; - - EXPECT_EQ(sizeof(SpdyIntrusiveLink<TestItem>), sizeof(void *) * 2); - - for (int i = 0; i < 10; ++i) { - TestItem *e = new TestItem; - e->n = i; - list1.push_front(e); - } - EXPECT_EQ(list1.size(), 10u); - - // Verify we can reverse a list because we defined swap for TestItem. - std::reverse(list1.begin(), list1.end()); - EXPECT_EQ(list1.size(), 10u); - - // Check both const and non-const forward iteration. - const TestList &clist1 = list1; - int i = 0; - TestList::iterator iter = list1.begin(); - for (; iter != list1.end(); ++iter, ++i) { - EXPECT_EQ(iter->n, i); - } - EXPECT_EQ(iter, clist1.end()); - EXPECT_NE(iter, clist1.begin()); - i = 0; - iter = list1.begin(); - for (; iter != list1.end(); ++iter, ++i) { - EXPECT_EQ(iter->n, i); - } - EXPECT_EQ(iter, clist1.end()); - EXPECT_NE(iter, clist1.begin()); - - EXPECT_EQ(list1.front().n, 0); - EXPECT_EQ(list1.back().n, 9); - - // Verify we can swap 2 lists. - TestList list2; - list2.swap(list1); - EXPECT_EQ(list1.size(), 0u); - EXPECT_EQ(list2.size(), 10u); - - // Check both const and non-const reverse iteration. - const TestList &clist2 = list2; - TestList::reverse_iterator riter = list2.rbegin(); - i = 9; - for (; riter != list2.rend(); ++riter, --i) { - EXPECT_EQ(riter->n, i); - } - EXPECT_EQ(riter, clist2.rend()); - EXPECT_NE(riter, clist2.rbegin()); - - riter = list2.rbegin(); - i = 9; - for (; riter != list2.rend(); ++riter, --i) { - EXPECT_EQ(riter->n, i); - } - EXPECT_EQ(riter, clist2.rend()); - EXPECT_NE(riter, clist2.rbegin()); - - while (!list2.empty()) { - TestItem *e = &list2.front(); - list2.pop_front(); - delete e; - } -} - -TEST(NewIntrusiveListTest, Erase) { - TestList l; - TestItem *e[10]; - - // Create a list with 10 items. - for (int i = 0; i < 10; ++i) { - e[i] = new TestItem; - l.push_front(e[i]); - } - - // Test that erase works. - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(l.size(), (10u - i)); - - TestList::iterator iter = l.erase(e[i]); - EXPECT_NE(iter, TestList::iterator(e[i])); - - EXPECT_EQ(l.size(), (10u - i - 1)); - delete e[i]; - } -} - -TEST(NewIntrusiveListTest, Insert) { - TestList l; - TestList::iterator iter = l.end(); - TestItem *e[10]; - - // Create a list with 10 items. - for (int i = 9; i >= 0; --i) { - e[i] = new TestItem; - iter = l.insert(iter, e[i]); - EXPECT_EQ(&(*iter), e[i]); - } - - EXPECT_EQ(l.size(), 10u); - - // Verify insertion order. - iter = l.begin(); - for (TestItem *item : e) { - EXPECT_EQ(&(*iter), item); - iter = l.erase(item); - delete item; - } -} - -TEST(NewIntrusiveListTest, Move) { - // Move contructible. - - { // Move-construct from an empty list. - TestList src; - TestList dest(std::move(src)); - EXPECT_TRUE(dest.empty()); - } - - { // Move-construct from a single item list. - TestItem e; - TestList src; - src.push_front(&e); - - TestList dest(std::move(src)); - EXPECT_TRUE(src.empty()); // NOLINT bugprone-use-after-move - ASSERT_THAT(dest.size(), 1); - EXPECT_THAT(&dest.front(), &e); - EXPECT_THAT(&dest.back(), &e); - } - - { // Move-construct from a list with multiple items. - TestItem items[10]; - TestList src; - for (TestItem &e : items) src.push_back(&e); - - TestList dest(std::move(src)); - EXPECT_TRUE(src.empty()); // NOLINT bugprone-use-after-move - // Verify the items on the destination list. - ASSERT_THAT(dest.size(), 10); - int i = 0; - for (TestItem &e : dest) { - EXPECT_THAT(&e, &items[i++]) << " for index " << i; - } - } -} - -TEST(NewIntrusiveListTest, StaticInsertErase) { - TestList l; - TestItem e[2]; - TestList::iterator i = l.begin(); - TestList::insert(i, &e[0]); - TestList::insert(&e[0], &e[1]); - TestList::erase(&e[0]); - TestList::erase(TestList::iterator(&e[1])); - EXPECT_TRUE(l.empty()); -} - -TEST_F(IntrusiveListTest, Splice) { - // We verify that the contents of this secondary list aren't affected by any - // of the splices. - SpdyIntrusiveList<TestItem, ListId2> secondary_list; - for (int i = 0; i < 3; ++i) { - secondary_list.push_back(&e[i]); - } - - // Test the basic cases: - // - The lists range from 0 to 2 elements. - // - The insertion point ranges from begin() to end() - // - The transfered range has multiple sizes and locations in the source. - for (int l1_count = 0; l1_count < 3; ++l1_count) { - for (int l2_count = 0; l2_count < 3; ++l2_count) { - for (int pos = 0; pos <= l1_count; ++pos) { - for (int first = 0; first <= l2_count; ++first) { - for (int last = first; last <= l2_count; ++last) { - PrepareLists(l1_count, l2_count); - - l1.splice(std::next(l1.begin(), pos), std::next(l2.begin(), first), - std::next(l2.begin(), last)); - ll1.splice(std::next(ll1.begin(), pos), ll2, - std::next(ll2.begin(), first), - std::next(ll2.begin(), last)); - - CheckLists(); - - ASSERT_EQ(3u, secondary_list.size()); - for (int i = 0; i < 3; ++i) { - EXPECT_EQ(&e[i], &*std::next(secondary_list.begin(), i)); - } - } - } - } - } - } -} - -// Build up a set of classes which form "challenging" type hierarchies to use -// with an SpdyIntrusiveList. -struct BaseLinkId {}; -struct DerivedLinkId {}; - -struct AbstractBase : public SpdyIntrusiveLink<AbstractBase, BaseLinkId> { - virtual ~AbstractBase() = 0; - virtual std::string name() { return "AbstractBase"; } -}; -AbstractBase::~AbstractBase() {} -struct DerivedClass : public SpdyIntrusiveLink<DerivedClass, DerivedLinkId>, - public AbstractBase { - ~DerivedClass() override {} - std::string name() override { return "DerivedClass"; } -}; -struct VirtuallyDerivedBaseClass : public virtual AbstractBase { - ~VirtuallyDerivedBaseClass() override = 0; - std::string name() override { return "VirtuallyDerivedBaseClass"; } -}; -VirtuallyDerivedBaseClass::~VirtuallyDerivedBaseClass() {} -struct VirtuallyDerivedClassA - : public SpdyIntrusiveLink<VirtuallyDerivedClassA, DerivedLinkId>, - public virtual VirtuallyDerivedBaseClass { - ~VirtuallyDerivedClassA() override {} - std::string name() override { return "VirtuallyDerivedClassA"; } -}; -struct NonceClass { - virtual ~NonceClass() {} - int data_; -}; -struct VirtuallyDerivedClassB - : public SpdyIntrusiveLink<VirtuallyDerivedClassB, DerivedLinkId>, - public virtual NonceClass, - public virtual VirtuallyDerivedBaseClass { - ~VirtuallyDerivedClassB() override {} - std::string name() override { return "VirtuallyDerivedClassB"; } -}; -struct VirtuallyDerivedClassC - : public SpdyIntrusiveLink<VirtuallyDerivedClassC, DerivedLinkId>, - public virtual AbstractBase, - public virtual NonceClass, - public virtual VirtuallyDerivedBaseClass { - ~VirtuallyDerivedClassC() override {} - std::string name() override { return "VirtuallyDerivedClassC"; } -}; - -// Test for multiple layers between the element type and the link. -namespace templated_base_link { -template <typename T> -struct AbstractBase : public SpdyIntrusiveLink<T> { - virtual ~AbstractBase() = 0; -}; -template <typename T> -AbstractBase<T>::~AbstractBase() {} -struct DerivedClass : public AbstractBase<DerivedClass> { - int n; -}; -} // namespace templated_base_link - -TEST(NewIntrusiveListTest, HandleInheritanceHierarchies) { - { - SpdyIntrusiveList<DerivedClass, DerivedLinkId> list; - DerivedClass elements[2]; - EXPECT_TRUE(list.empty()); - list.push_back(&elements[0]); - EXPECT_EQ(1u, list.size()); - list.push_back(&elements[1]); - EXPECT_EQ(2u, list.size()); - list.pop_back(); - EXPECT_EQ(1u, list.size()); - list.pop_back(); - EXPECT_TRUE(list.empty()); - } - { - SpdyIntrusiveList<VirtuallyDerivedClassA, DerivedLinkId> list; - VirtuallyDerivedClassA elements[2]; - EXPECT_TRUE(list.empty()); - list.push_back(&elements[0]); - EXPECT_EQ(1u, list.size()); - list.push_back(&elements[1]); - EXPECT_EQ(2u, list.size()); - list.pop_back(); - EXPECT_EQ(1u, list.size()); - list.pop_back(); - EXPECT_TRUE(list.empty()); - } - { - SpdyIntrusiveList<VirtuallyDerivedClassC, DerivedLinkId> list; - VirtuallyDerivedClassC elements[2]; - EXPECT_TRUE(list.empty()); - list.push_back(&elements[0]); - EXPECT_EQ(1u, list.size()); - list.push_back(&elements[1]); - EXPECT_EQ(2u, list.size()); - list.pop_back(); - EXPECT_EQ(1u, list.size()); - list.pop_back(); - EXPECT_TRUE(list.empty()); - } - { - SpdyIntrusiveList<AbstractBase, BaseLinkId> list; - DerivedClass d1; - VirtuallyDerivedClassA d2; - VirtuallyDerivedClassB d3; - VirtuallyDerivedClassC d4; - EXPECT_TRUE(list.empty()); - list.push_back(&d1); - EXPECT_EQ(1u, list.size()); - list.push_back(&d2); - EXPECT_EQ(2u, list.size()); - list.push_back(&d3); - EXPECT_EQ(3u, list.size()); - list.push_back(&d4); - EXPECT_EQ(4u, list.size()); - SpdyIntrusiveList<AbstractBase, BaseLinkId>::iterator it = list.begin(); - EXPECT_EQ("DerivedClass", (it++)->name()); - EXPECT_EQ("VirtuallyDerivedClassA", (it++)->name()); - EXPECT_EQ("VirtuallyDerivedClassB", (it++)->name()); - EXPECT_EQ("VirtuallyDerivedClassC", (it++)->name()); - } - { - SpdyIntrusiveList<templated_base_link::DerivedClass> list; - templated_base_link::DerivedClass elements[2]; - EXPECT_TRUE(list.empty()); - list.push_back(&elements[0]); - EXPECT_EQ(1u, list.size()); - list.push_back(&elements[1]); - EXPECT_EQ(2u, list.size()); - list.pop_back(); - EXPECT_EQ(1u, list.size()); - list.pop_back(); - EXPECT_TRUE(list.empty()); - } -} - -class IntrusiveListTagTypeTest : public quiche::test::QuicheTest { - protected: - struct Tag {}; - class Element : public SpdyIntrusiveLink<Element, Tag> {}; -}; - -TEST_F(IntrusiveListTagTypeTest, TagTypeListID) { - SpdyIntrusiveList<Element, Tag> list; - { - Element e; - list.push_back(&e); - } -} - -} // namespace test -} // namespace spdy
diff --git a/quiche/spdy/core/spdy_pinnable_buffer_piece.cc b/quiche/spdy/core/spdy_pinnable_buffer_piece.cc deleted file mode 100644 index 86e67ac..0000000 --- a/quiche/spdy/core/spdy_pinnable_buffer_piece.cc +++ /dev/null
@@ -1,37 +0,0 @@ -// 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 "quiche/spdy/core/spdy_pinnable_buffer_piece.h" - -#include <algorithm> -#include <cstddef> - -namespace spdy { - -SpdyPinnableBufferPiece::SpdyPinnableBufferPiece() - : buffer_(nullptr), length_(0) {} - -SpdyPinnableBufferPiece::~SpdyPinnableBufferPiece() = default; - -void SpdyPinnableBufferPiece::Pin() { - if (!storage_ && buffer_ != nullptr && length_ != 0) { - storage_.reset(new char[length_]); - std::copy(buffer_, buffer_ + length_, storage_.get()); - buffer_ = storage_.get(); - } -} - -void SpdyPinnableBufferPiece::Swap(SpdyPinnableBufferPiece* other) { - size_t length = length_; - length_ = other->length_; - other->length_ = length; - - const char* buffer = buffer_; - buffer_ = other->buffer_; - other->buffer_ = buffer; - - storage_.swap(other->storage_); -} - -} // namespace spdy
diff --git a/quiche/spdy/core/spdy_pinnable_buffer_piece.h b/quiche/spdy/core/spdy_pinnable_buffer_piece.h deleted file mode 100644 index d73a400..0000000 --- a/quiche/spdy/core/spdy_pinnable_buffer_piece.h +++ /dev/null
@@ -1,53 +0,0 @@ -// 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. - -#ifndef QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_ -#define QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_ - -#include <stddef.h> - -#include <memory> - -#include "absl/strings/string_view.h" -#include "quiche/common/platform/api/quiche_export.h" - -namespace spdy { - -class SpdyPrefixedBufferReader; - -// Helper class of SpdyPrefixedBufferReader. -// Represents a piece of consumed buffer which may (or may not) own its -// underlying storage. Users may "pin" the buffer at a later time to ensure -// a SpdyPinnableBufferPiece owns and retains storage of the buffer. -struct QUICHE_EXPORT SpdyPinnableBufferPiece { - public: - SpdyPinnableBufferPiece(); - ~SpdyPinnableBufferPiece(); - - const char* buffer() const { return buffer_; } - - explicit operator absl::string_view() const { - return absl::string_view(buffer_, length_); - } - - // Allocates and copies the buffer to internal storage. - void Pin(); - - bool IsPinned() const { return storage_ != nullptr; } - - // Swaps buffers, including internal storage, with |other|. - void Swap(SpdyPinnableBufferPiece* other); - - private: - friend class SpdyPrefixedBufferReader; - - const char* buffer_; - size_t length_; - // Null iff |buffer_| isn't pinned. - std::unique_ptr<char[]> storage_; -}; - -} // namespace spdy - -#endif // QUICHE_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
diff --git a/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc b/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc deleted file mode 100644 index 9e3f804..0000000 --- a/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc +++ /dev/null
@@ -1,81 +0,0 @@ -// 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 "quiche/spdy/core/spdy_pinnable_buffer_piece.h" - -#include <string> - -#include "absl/strings/string_view.h" -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/spdy/core/spdy_prefixed_buffer_reader.h" - -namespace spdy { - -namespace test { - -class SpdyPinnableBufferPieceTest : public quiche::test::QuicheTest { - protected: - SpdyPrefixedBufferReader Build(const std::string& prefix, - const std::string& suffix) { - prefix_ = prefix; - suffix_ = suffix; - return SpdyPrefixedBufferReader(prefix_.data(), prefix_.length(), - suffix_.data(), suffix_.length()); - } - std::string prefix_, suffix_; -}; - -TEST_F(SpdyPinnableBufferPieceTest, Pin) { - SpdyPrefixedBufferReader reader = Build("foobar", ""); - SpdyPinnableBufferPiece piece; - EXPECT_TRUE(reader.ReadN(6, &piece)); - - // Piece points to underlying prefix storage. - EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); - EXPECT_FALSE(piece.IsPinned()); - EXPECT_EQ(prefix_.data(), piece.buffer()); - - piece.Pin(); - - // Piece now points to allocated storage. - EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); - EXPECT_TRUE(piece.IsPinned()); - EXPECT_NE(prefix_.data(), piece.buffer()); - - // Pinning again has no effect. - const char* buffer = piece.buffer(); - piece.Pin(); - EXPECT_EQ(buffer, piece.buffer()); -} - -TEST_F(SpdyPinnableBufferPieceTest, Swap) { - SpdyPrefixedBufferReader reader = Build("foobar", ""); - SpdyPinnableBufferPiece piece1, piece2; - EXPECT_TRUE(reader.ReadN(4, &piece1)); - EXPECT_TRUE(reader.ReadN(2, &piece2)); - - piece1.Pin(); - - EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece1)); - EXPECT_TRUE(piece1.IsPinned()); - EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece2)); - EXPECT_FALSE(piece2.IsPinned()); - - piece1.Swap(&piece2); - - EXPECT_EQ(absl::string_view("ar"), absl::string_view(piece1)); - EXPECT_FALSE(piece1.IsPinned()); - EXPECT_EQ(absl::string_view("foob"), absl::string_view(piece2)); - EXPECT_TRUE(piece2.IsPinned()); - - SpdyPinnableBufferPiece empty; - piece2.Swap(&empty); - - EXPECT_EQ(absl::string_view(""), absl::string_view(piece2)); - EXPECT_FALSE(piece2.IsPinned()); -} - -} // namespace test - -} // namespace spdy
diff --git a/quiche/spdy/core/spdy_prefixed_buffer_reader.cc b/quiche/spdy/core/spdy_prefixed_buffer_reader.cc deleted file mode 100644 index 843e139..0000000 --- a/quiche/spdy/core/spdy_prefixed_buffer_reader.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// 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 "quiche/spdy/core/spdy_prefixed_buffer_reader.h" - -#include <algorithm> -#include <cstddef> - -#include "quiche/common/platform/api/quiche_logging.h" -#include "quiche/spdy/core/spdy_pinnable_buffer_piece.h" - -namespace spdy { - -SpdyPrefixedBufferReader::SpdyPrefixedBufferReader(const char* prefix, - size_t prefix_length, - const char* suffix, - size_t suffix_length) - : prefix_(prefix), - suffix_(suffix), - prefix_length_(prefix_length), - suffix_length_(suffix_length) {} - -size_t SpdyPrefixedBufferReader::Available() { - return prefix_length_ + suffix_length_; -} - -bool SpdyPrefixedBufferReader::ReadN(size_t count, char* out) { - if (Available() < count) { - return false; - } - - if (prefix_length_ >= count) { - // Read is fully satisfied by the prefix. - std::copy(prefix_, prefix_ + count, out); - prefix_ += count; - prefix_length_ -= count; - return true; - } else if (prefix_length_ != 0) { - // Read is partially satisfied by the prefix. - out = std::copy(prefix_, prefix_ + prefix_length_, out); - count -= prefix_length_; - prefix_length_ = 0; - // Fallthrough to suffix read. - } - QUICHE_DCHECK(suffix_length_ >= count); - // Read is satisfied by the suffix. - std::copy(suffix_, suffix_ + count, out); - suffix_ += count; - suffix_length_ -= count; - return true; -} - -bool SpdyPrefixedBufferReader::ReadN(size_t count, - SpdyPinnableBufferPiece* out) { - if (Available() < count) { - return false; - } - - out->storage_.reset(); - out->length_ = count; - - if (prefix_length_ >= count) { - // Read is fully satisfied by the prefix. - out->buffer_ = prefix_; - prefix_ += count; - prefix_length_ -= count; - return true; - } else if (prefix_length_ != 0) { - // Read is only partially satisfied by the prefix. We need to allocate - // contiguous storage as the read spans the prefix & suffix. - out->storage_.reset(new char[count]); - out->buffer_ = out->storage_.get(); - ReadN(count, out->storage_.get()); - return true; - } else { - QUICHE_DCHECK(suffix_length_ >= count); - // Read is fully satisfied by the suffix. - out->buffer_ = suffix_; - suffix_ += count; - suffix_length_ -= count; - return true; - } -} - -} // namespace spdy
diff --git a/quiche/spdy/core/spdy_prefixed_buffer_reader.h b/quiche/spdy/core/spdy_prefixed_buffer_reader.h deleted file mode 100644 index c102ee6..0000000 --- a/quiche/spdy/core/spdy_prefixed_buffer_reader.h +++ /dev/null
@@ -1,43 +0,0 @@ -// 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. - -#ifndef QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_ -#define QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_ - -#include <stddef.h> - -#include "quiche/common/platform/api/quiche_export.h" -#include "quiche/spdy/core/spdy_pinnable_buffer_piece.h" - -namespace spdy { - -// Reader class which simplifies reading contiguously from -// from a disjoint buffer prefix & suffix. -class QUICHE_EXPORT SpdyPrefixedBufferReader { - public: - SpdyPrefixedBufferReader(const char* prefix, size_t prefix_length, - const char* suffix, size_t suffix_length); - - // Returns number of bytes available to be read. - size_t Available(); - - // Reads |count| bytes, copying into |*out|. Returns true on success, - // false if not enough bytes were available. - bool ReadN(size_t count, char* out); - - // Reads |count| bytes, returned in |*out|. Returns true on success, - // false if not enough bytes were available. - bool ReadN(size_t count, SpdyPinnableBufferPiece* out); - - private: - const char* prefix_; - const char* suffix_; - - size_t prefix_length_; - size_t suffix_length_; -}; - -} // namespace spdy - -#endif // QUICHE_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
diff --git a/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc b/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc deleted file mode 100644 index 0c67d8c..0000000 --- a/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc +++ /dev/null
@@ -1,132 +0,0 @@ -// 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 "quiche/spdy/core/spdy_prefixed_buffer_reader.h" - -#include <string> - -#include "absl/strings/string_view.h" -#include "quiche/common/platform/api/quiche_test.h" -#include "quiche/spdy/core/spdy_pinnable_buffer_piece.h" - -namespace spdy { - -namespace test { - -using testing::ElementsAreArray; - -class SpdyPrefixedBufferReaderTest : public quiche::test::QuicheTest { - protected: - SpdyPrefixedBufferReader Build(const std::string& prefix, - const std::string& suffix) { - prefix_ = prefix; - suffix_ = suffix; - return SpdyPrefixedBufferReader(prefix_.data(), prefix_.length(), - suffix_.data(), suffix_.length()); - } - std::string prefix_, suffix_; -}; - -TEST_F(SpdyPrefixedBufferReaderTest, ReadRawFromPrefix) { - SpdyPrefixedBufferReader reader = Build("foobar", ""); - EXPECT_EQ(6u, reader.Available()); - - char buffer[] = "123456"; - EXPECT_FALSE(reader.ReadN(10, buffer)); // Not enough buffer. - EXPECT_TRUE(reader.ReadN(6, buffer)); - EXPECT_THAT(buffer, ElementsAreArray("foobar")); - EXPECT_EQ(0u, reader.Available()); -} - -TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromPrefix) { - SpdyPrefixedBufferReader reader = Build("foobar", ""); - EXPECT_EQ(6u, reader.Available()); - - SpdyPinnableBufferPiece piece; - EXPECT_FALSE(reader.ReadN(10, &piece)); // Not enough buffer. - EXPECT_TRUE(reader.ReadN(6, &piece)); - EXPECT_FALSE(piece.IsPinned()); - EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); - EXPECT_EQ(0u, reader.Available()); -} - -TEST_F(SpdyPrefixedBufferReaderTest, ReadRawFromSuffix) { - SpdyPrefixedBufferReader reader = Build("", "foobar"); - EXPECT_EQ(6u, reader.Available()); - - char buffer[] = "123456"; - EXPECT_FALSE(reader.ReadN(10, buffer)); // Not enough buffer. - EXPECT_TRUE(reader.ReadN(6, buffer)); - EXPECT_THAT(buffer, ElementsAreArray("foobar")); - EXPECT_EQ(0u, reader.Available()); -} - -TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceFromSuffix) { - SpdyPrefixedBufferReader reader = Build("", "foobar"); - EXPECT_EQ(6u, reader.Available()); - - SpdyPinnableBufferPiece piece; - EXPECT_FALSE(reader.ReadN(10, &piece)); // Not enough buffer. - EXPECT_TRUE(reader.ReadN(6, &piece)); - EXPECT_FALSE(piece.IsPinned()); - EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); - EXPECT_EQ(0u, reader.Available()); -} - -TEST_F(SpdyPrefixedBufferReaderTest, ReadRawSpanning) { - SpdyPrefixedBufferReader reader = Build("foob", "ar"); - EXPECT_EQ(6u, reader.Available()); - - char buffer[] = "123456"; - EXPECT_FALSE(reader.ReadN(10, buffer)); // Not enough buffer. - EXPECT_TRUE(reader.ReadN(6, buffer)); - EXPECT_THAT(buffer, ElementsAreArray("foobar")); - EXPECT_EQ(0u, reader.Available()); -} - -TEST_F(SpdyPrefixedBufferReaderTest, ReadPieceSpanning) { - SpdyPrefixedBufferReader reader = Build("foob", "ar"); - EXPECT_EQ(6u, reader.Available()); - - SpdyPinnableBufferPiece piece; - EXPECT_FALSE(reader.ReadN(10, &piece)); // Not enough buffer. - EXPECT_TRUE(reader.ReadN(6, &piece)); - EXPECT_TRUE(piece.IsPinned()); - EXPECT_EQ(absl::string_view("foobar"), absl::string_view(piece)); - EXPECT_EQ(0u, reader.Available()); -} - -TEST_F(SpdyPrefixedBufferReaderTest, ReadMixed) { - SpdyPrefixedBufferReader reader = Build("abcdef", "hijkl"); - EXPECT_EQ(11u, reader.Available()); - - char buffer[] = "1234"; - SpdyPinnableBufferPiece piece; - - EXPECT_TRUE(reader.ReadN(3, buffer)); - EXPECT_THAT(buffer, ElementsAreArray("abc4")); - EXPECT_EQ(8u, reader.Available()); - - EXPECT_TRUE(reader.ReadN(2, buffer)); - EXPECT_THAT(buffer, ElementsAreArray("dec4")); - EXPECT_EQ(6u, reader.Available()); - - EXPECT_TRUE(reader.ReadN(3, &piece)); - EXPECT_EQ(absl::string_view("fhi"), absl::string_view(piece)); - EXPECT_TRUE(piece.IsPinned()); - EXPECT_EQ(3u, reader.Available()); - - EXPECT_TRUE(reader.ReadN(2, &piece)); - EXPECT_EQ(absl::string_view("jk"), absl::string_view(piece)); - EXPECT_FALSE(piece.IsPinned()); - EXPECT_EQ(1u, reader.Available()); - - EXPECT_TRUE(reader.ReadN(1, buffer)); - EXPECT_THAT(buffer, ElementsAreArray("lec4")); - EXPECT_EQ(0u, reader.Available()); -} - -} // namespace test - -} // namespace spdy