Chromium Code Reviews| Index: Source/modules/fetch/FetchDataLoader.cpp |
| diff --git a/Source/modules/fetch/FetchDataLoader.cpp b/Source/modules/fetch/FetchDataLoader.cpp |
| index 643042b67f85c7ff31dd5f2ceaf876188ab70a01..34fadd95c28fc43b94cf3d53dd7fdd80005cdfbf 100644 |
| --- a/Source/modules/fetch/FetchDataLoader.cpp |
| +++ b/Source/modules/fetch/FetchDataLoader.cpp |
| @@ -212,6 +212,100 @@ protected: |
| OwnPtr<ArrayBufferBuilder> m_rawData; |
| }; |
| +class FetchDataLoaderAsStream |
| + : public FetchDataLoader |
| + , public WebDataConsumerHandle::Client { |
| +public: |
| + explicit FetchDataLoaderAsStream(Stream* outStream) |
| + : m_client(nullptr) |
| + , m_outStream(outStream) { } |
| + |
| + DEFINE_INLINE_VIRTUAL_TRACE() |
| + { |
| + FetchDataLoader::trace(visitor); |
| + visitor->trace(m_client); |
| + visitor->trace(m_outStream); |
| + } |
| + |
| +protected: |
| + void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client) override |
| + { |
| + ASSERT(!m_client); |
| + ASSERT(!m_reader); |
| + m_client = client; |
| + m_reader = handle->obtainReader(this); |
| + } |
| + |
| + void didGetReadable() override |
| + { |
| + ASSERT(m_client); |
| + ASSERT(m_reader); |
| + |
| + while (true) { |
| + const void* buffer; |
| + size_t available; |
| + WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); |
| + |
| + bool needToFlush = false; |
|
yhirano
2015/06/25 10:53:33
This variable should be defined out of the loop.
hiroshige
2015/06/25 11:12:26
Done.
|
| + |
| + switch (result) { |
| + case WebDataConsumerHandle::Ok: |
| + m_outStream->addData(static_cast<const char*>(buffer), available); |
| + m_reader->endRead(available); |
|
yhirano
2015/06/25 10:53:33
needToFlush = true
hiroshige
2015/06/25 11:12:26
Done.
|
| + break; |
| + |
| + case WebDataConsumerHandle::Done: |
| + m_reader.clear(); |
| + if (needToFlush) |
| + m_outStream->flush(); |
| + m_outStream->finalize(); |
| + m_client->didFetchDataLoadedStream(); |
| + cleanup(); |
| + return; |
| + |
| + case WebDataConsumerHandle::ShouldWait: |
| + if (needToFlush) |
| + m_outStream->flush(); |
| + return; |
| + |
| + case WebDataConsumerHandle::Busy: |
| + case WebDataConsumerHandle::ResourceExhausted: |
| + case WebDataConsumerHandle::UnexpectedError: |
| + // If the stream is aborted soon after the stream is registered |
| + // to the StreamRegistry, ServiceWorkerURLRequestJob may not |
| + // notice the error and continue waiting forever. |
| + // FIXME: Add new message to report the error to the browser |
| + // process. |
| + m_reader.clear(); |
| + if (needToFlush) |
| + m_outStream->flush(); |
|
yhirano
2015/06/25 10:53:33
I'm not sure if flushing is needed in this case.
hiroshige
2015/06/25 11:12:26
Done.
|
| + m_outStream->abort(); |
| + m_client->didFetchDataLoadFailed(); |
| + cleanup(); |
| + return; |
| + } |
| + } |
| + } |
| + |
| + void cancel() override |
| + { |
| + cleanup(); |
| + } |
| + |
| + void cleanup() |
| + { |
| + m_reader.clear(); |
| + m_client.clear(); |
| + m_outStream.clear(); |
| + } |
| + |
| + OwnPtr<FetchDataConsumerHandle::Reader> m_reader; |
| + Member<FetchDataLoader::Client> m_client; |
| + |
| + Member<Stream> m_outStream; |
| +}; |
| + |
| + |
| } // namespace |
| FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle(const String& mimeType) |
| @@ -229,4 +323,9 @@ FetchDataLoader* FetchDataLoader::createLoaderAsString() |
| return new FetchDataLoaderAsArrayBufferOrString(FetchDataLoaderAsArrayBufferOrString::LoadAsString); |
| } |
| +FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) |
| +{ |
| + return new FetchDataLoaderAsStream(outStream); |
| +} |
| + |
| } // namespace blink |