| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2015 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 "modules/fetch/BytesConsumerTestUtil.h" |
| 6 |
| 7 #include "core/dom/ExecutionContext.h" |
| 8 #include "core/dom/TaskRunnerHelper.h" |
| 9 #include "platform/testing/UnitTestHelpers.h" |
| 10 #include "public/platform/WebTaskRunner.h" |
| 11 #include "wtf/Assertions.h" |
| 12 #include "wtf/Functional.h" |
| 13 |
| 14 namespace blink { |
| 15 |
| 16 using Result = BytesConsumer::Result; |
| 17 |
| 18 BytesConsumerTestUtil::ReplayingBytesConsumer::ReplayingBytesConsumer(ExecutionC
ontext* executionContext) |
| 19 : m_executionContext(executionContext) |
| 20 { |
| 21 } |
| 22 |
| 23 BytesConsumerTestUtil::ReplayingBytesConsumer::~ReplayingBytesConsumer() |
| 24 { |
| 25 } |
| 26 |
| 27 Result BytesConsumerTestUtil::ReplayingBytesConsumer::beginRead(const char** buf
fer, size_t* available) |
| 28 { |
| 29 ++m_notificationToken; |
| 30 if (m_commands.isEmpty()) { |
| 31 switch (m_state) { |
| 32 case BytesConsumer::InternalState::Readable: |
| 33 case BytesConsumer::InternalState::Waiting: |
| 34 return Result::ShouldWait; |
| 35 case BytesConsumer::InternalState::Closed: |
| 36 return Result::Done; |
| 37 case BytesConsumer::InternalState::Errored: |
| 38 return Result::Error; |
| 39 } |
| 40 } |
| 41 const Command& command = m_commands[0]; |
| 42 switch (command.getName()) { |
| 43 case Command::Data: |
| 44 DCHECK_LE(m_offset, command.body().size()); |
| 45 *buffer = command.body().data() + m_offset; |
| 46 *available = command.body().size() - m_offset; |
| 47 return Result::Ok; |
| 48 case Command::Done: |
| 49 m_commands.removeFirst(); |
| 50 close(); |
| 51 return Result::Done; |
| 52 case Command::Error: |
| 53 m_commands.removeFirst(); |
| 54 error(Error(String::fromUTF8(command.body().data(), command.body().size(
)))); |
| 55 return Result::Error; |
| 56 case Command::Wait: |
| 57 m_commands.removeFirst(); |
| 58 m_state = InternalState::Waiting; |
| 59 TaskRunnerHelper::get(TaskType::Networking, m_executionContext)->postTas
k( |
| 60 BLINK_FROM_HERE, |
| 61 WTF::bind(&ReplayingBytesConsumer::notifyAsReadable, wrapPersistent(
this), m_notificationToken)); |
| 62 return Result::ShouldWait; |
| 63 } |
| 64 NOTREACHED(); |
| 65 return Result::Error; |
| 66 } |
| 67 |
| 68 Result BytesConsumerTestUtil::ReplayingBytesConsumer::endRead(size_t read) |
| 69 { |
| 70 DCHECK(!m_commands.isEmpty()); |
| 71 const Command& command = m_commands[0]; |
| 72 DCHECK_EQ(Command::Data, command.getName()); |
| 73 m_offset += read; |
| 74 DCHECK_LE(m_offset, command.body().size()); |
| 75 if (m_offset < command.body().size()) |
| 76 return Result::Ok; |
| 77 |
| 78 m_offset = 0; |
| 79 m_commands.removeFirst(); |
| 80 return Result::Ok; |
| 81 } |
| 82 |
| 83 void BytesConsumerTestUtil::ReplayingBytesConsumer::setClient(Client* client) |
| 84 { |
| 85 DCHECK(!m_client); |
| 86 DCHECK(client); |
| 87 m_client = client; |
| 88 ++m_notificationToken; |
| 89 } |
| 90 |
| 91 void BytesConsumerTestUtil::ReplayingBytesConsumer::clearClient() |
| 92 { |
| 93 DCHECK(m_client); |
| 94 m_client = nullptr; |
| 95 ++m_notificationToken; |
| 96 } |
| 97 |
| 98 void BytesConsumerTestUtil::ReplayingBytesConsumer::cancel() |
| 99 { |
| 100 close(); |
| 101 m_isCancelled = true; |
| 102 } |
| 103 |
| 104 BytesConsumer::PublicState BytesConsumerTestUtil::ReplayingBytesConsumer::getPub
licState() const |
| 105 { |
| 106 return getPublicStateFromInternalState(m_state); |
| 107 } |
| 108 |
| 109 BytesConsumer::Error BytesConsumerTestUtil::ReplayingBytesConsumer::getError() c
onst |
| 110 { |
| 111 return m_error; |
| 112 } |
| 113 |
| 114 void BytesConsumerTestUtil::ReplayingBytesConsumer::notifyAsReadable(int notific
ationToken) |
| 115 { |
| 116 if (m_notificationToken != notificationToken) { |
| 117 // The notification is cancelled. |
| 118 return; |
| 119 } |
| 120 DCHECK(m_client); |
| 121 DCHECK_NE(InternalState::Closed, m_state); |
| 122 DCHECK_NE(InternalState::Errored, m_state); |
| 123 m_client->onStateChange(); |
| 124 } |
| 125 |
| 126 void BytesConsumerTestUtil::ReplayingBytesConsumer::close() |
| 127 { |
| 128 m_commands.clear(); |
| 129 m_offset = 0; |
| 130 m_state = InternalState::Closed; |
| 131 ++m_notificationToken; |
| 132 } |
| 133 |
| 134 void BytesConsumerTestUtil::ReplayingBytesConsumer::error(const Error& e) |
| 135 { |
| 136 m_commands.clear(); |
| 137 m_offset = 0; |
| 138 m_error = e; |
| 139 m_state = InternalState::Errored; |
| 140 ++m_notificationToken; |
| 141 } |
| 142 |
| 143 DEFINE_TRACE(BytesConsumerTestUtil::ReplayingBytesConsumer) |
| 144 { |
| 145 visitor->trace(m_executionContext); |
| 146 visitor->trace(m_client); |
| 147 BytesConsumer::trace(visitor); |
| 148 } |
| 149 |
| 150 BytesConsumerTestUtil::Reader::Reader(BytesConsumer* consumer) |
| 151 : m_consumer(consumer) |
| 152 { |
| 153 m_consumer->setClient(this); |
| 154 } |
| 155 |
| 156 void BytesConsumerTestUtil::Reader::onStateChange() |
| 157 { |
| 158 while (true) { |
| 159 char buffer[3]; |
| 160 size_t read = 0; |
| 161 switch (m_consumer->read(buffer, sizeof(buffer), &read)) { |
| 162 case BytesConsumer::Result::Ok: |
| 163 m_data.append(buffer, read); |
| 164 break; |
| 165 case BytesConsumer::Result::ShouldWait: |
| 166 return; |
| 167 case BytesConsumer::Result::Done: |
| 168 m_result = BytesConsumer::Result::Done; |
| 169 return; |
| 170 case BytesConsumer::Result::Error: |
| 171 m_result = BytesConsumer::Result::Error; |
| 172 return; |
| 173 } |
| 174 } |
| 175 } |
| 176 |
| 177 std::pair<BytesConsumer::Result, Vector<char>> BytesConsumerTestUtil::Reader::ru
n() |
| 178 { |
| 179 onStateChange(); |
| 180 while (m_result != BytesConsumer::Result::Done && m_result != BytesConsumer:
:Result::Error) |
| 181 testing::runPendingTasks(); |
| 182 return std::make_pair(m_result, std::move(m_data)); |
| 183 } |
| 184 |
| 185 BytesConsumerTestUtil::TwoPhaseReader::TwoPhaseReader(BytesConsumer* consumer) |
| 186 : m_consumer(consumer) |
| 187 { |
| 188 m_consumer->setClient(this); |
| 189 } |
| 190 |
| 191 |
| 192 void BytesConsumerTestUtil::TwoPhaseReader::onStateChange() |
| 193 { |
| 194 while (true) { |
| 195 const char* buffer = nullptr; |
| 196 size_t available = 0; |
| 197 switch (m_consumer->beginRead(&buffer, &available)) { |
| 198 case BytesConsumer::Result::Ok: { |
| 199 size_t read = std::max(static_cast<size_t>(3), available); |
| 200 m_data.append(buffer, read); |
| 201 m_consumer->endRead(read); |
| 202 break; |
| 203 } |
| 204 case BytesConsumer::Result::ShouldWait: |
| 205 return; |
| 206 case BytesConsumer::Result::Done: |
| 207 m_result = BytesConsumer::Result::Done; |
| 208 return; |
| 209 case BytesConsumer::Result::Error: |
| 210 m_result = BytesConsumer::Result::Error; |
| 211 return; |
| 212 } |
| 213 } |
| 214 } |
| 215 |
| 216 std::pair<BytesConsumer::Result, Vector<char>> BytesConsumerTestUtil::TwoPhaseRe
ader::run() |
| 217 { |
| 218 onStateChange(); |
| 219 while (m_result != BytesConsumer::Result::Done && m_result != BytesConsumer:
:Result::Error) |
| 220 testing::runPendingTasks(); |
| 221 return std::make_pair(m_result, std::move(m_data)); |
| 222 } |
| 223 |
| 224 } // namespace blink |
| OLD | NEW |