Chromium Code Reviews| Index: Source/modules/fetch/FetchDataLoader.cpp |
| diff --git a/Source/modules/fetch/FetchDataLoader.cpp b/Source/modules/fetch/FetchDataLoader.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..65bdbc532766b06a5c7cd1b4e7305b7959cf302b |
| --- /dev/null |
| +++ b/Source/modules/fetch/FetchDataLoader.cpp |
| @@ -0,0 +1,198 @@ |
| +// Copyright 2015 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 "config.h" |
| +#include "modules/fetch/FetchDataLoader.h" |
|
yhirano
2015/06/17 05:18:53
+wtf/text/WTFString.h
hiroshige
2015/06/17 08:48:54
Done.
|
| + |
| +namespace blink { |
| + |
| +namespace { |
| + |
| +class FetchDataLoaderAsBlobHandle |
| + : public FetchDataLoader |
| + , public WebDataConsumerHandle::Client { |
| +public: |
| + FetchDataLoaderAsBlobHandle(const String& mimeType) |
|
yhirano
2015/06/17 05:18:53
explicit
hiroshige
2015/06/17 08:48:55
Done.
|
| + : m_mimeType(mimeType) { } |
| + |
| +private: |
| + void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client) override |
| + { |
| + ASSERT(!m_client); |
| + ASSERT(!m_reader); |
| + |
| + m_client = client; |
| + m_reader = handle->obtainReader(this); |
|
yhirano
2015/06/17 05:18:53
Please say that passing |this| is safe because |th
hiroshige
2015/06/17 08:48:55
Done.
|
| + RefPtr<BlobDataHandle> blobHandle = m_reader->blobDataHandle(); |
| + if (blobHandle && blobHandle->size() != kuint64max) { |
| + // If the size of |blobHandle| is set correctly, creates Blob from |
| + // it. |
| + m_reader.clear(); |
| + if (blobHandle->type() != m_mimeType) { |
| + // A new BlobDataHandle is created to override the Blob's type. |
| + m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(blobHandle->uuid(), m_mimeType, blobHandle->size())); |
|
yhirano
2015/06/17 05:18:53
[optional] for m_client->call() pattern, I think
{
hiroshige
2015/06/17 08:48:55
Done.
|
| + } else { |
| + m_client->didFetchDataLoadedBlobHandle(blobHandle); |
| + } |
| + // Here |this| might be already destructed. |
| + return; |
| + } |
| + |
| + // If the size is not set, read from |m_reader| and create a new blob. |
| + m_blobData = BlobData::create(); |
| + m_blobData->setContentType(m_mimeType); |
| + } |
| + |
| + 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); |
| + |
| + switch (result) { |
| + case WebDataConsumerHandle::Ok: |
| + m_blobData->appendBytes(buffer, available); |
| + m_reader->endRead(available); |
| + break; |
| + |
| + case WebDataConsumerHandle::Done: { |
| + m_reader.clear(); |
| + long long size = m_blobData->length(); |
| + m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(m_blobData.release(), size)); |
| + return; |
| + } |
| + |
| + case WebDataConsumerHandle::ShouldWait: |
| + return; |
| + |
| + case WebDataConsumerHandle::Busy: |
| + case WebDataConsumerHandle::ResourceExhausted: |
| + case WebDataConsumerHandle::UnexpectedError: |
| + m_reader.clear(); |
| + m_client->didFetchDataLoadFailed(); |
| + return; |
| + } |
| + } |
| + } |
| + |
| + String m_mimeType; |
| + OwnPtr<BlobData> m_blobData; |
| +}; |
| + |
| +class FetchDataLoaderAsArrayBufferOrString |
| + : public FetchDataLoader |
| + , public WebDataConsumerHandle::Client { |
| +public: |
| + enum LoadType { |
| + LoadAsArrayBuffer, |
| + LoadAsString |
| + }; |
| + |
| + FetchDataLoaderAsArrayBufferOrString(LoadType loadType) |
| + : m_loadType(loadType) { } |
| + |
| +protected: |
| + void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client) override |
| + { |
| + ASSERT(!m_client); |
| + ASSERT(!m_rawData); |
| + ASSERT(!m_reader); |
| + m_client = client; |
| + m_rawData = adoptPtr(new ArrayBufferBuilder()); |
| + m_reader = handle->obtainReader(this); |
| + } |
| + |
| + void didGetReadable() override |
| + { |
| + ASSERT(m_client); |
| + ASSERT(m_rawData); |
| + ASSERT(m_reader); |
| + |
| + while (true) { |
| + const void* buffer; |
| + size_t available; |
| + WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); |
| + |
| + switch (result) { |
| + case WebDataConsumerHandle::Ok: |
| + if (available > 0) { |
| + unsigned bytesAppended = m_rawData->append(static_cast<const char*>(buffer), available); |
| + if (!bytesAppended) { |
| + m_reader->endRead(0); |
| + error(); |
| + return; |
| + } |
| + ASSERT(bytesAppended == available); |
| + m_reader->endRead(available); |
|
yhirano
2015/06/17 05:18:53
You can move this endRead call out of this block a
hiroshige
2015/06/17 08:48:54
Done.
|
| + } else { |
| + m_reader->endRead(0); |
| + } |
| + break; |
| + |
| + case WebDataConsumerHandle::Done: |
| + m_reader.clear(); |
| + switch (m_loadType) { |
| + case LoadAsArrayBuffer: |
| + m_client->didFetchDataLoadedArrayBuffer(DOMArrayBuffer::create(m_rawData->toArrayBuffer())); |
| + break; |
| + case LoadAsString: |
| + m_client->didFetchDataLoadedString(m_rawData->toString()); |
| + break; |
| + default: |
|
yhirano
2015/06/17 05:18:53
You don't need this default clause (compiler check
hiroshige
2015/06/17 08:48:54
Done.
|
| + ASSERT_NOT_REACHED(); |
| + } |
| + // Here |this| might be already destructed. |
| + return; |
| + |
| + case WebDataConsumerHandle::ShouldWait: |
| + return; |
| + |
| + case WebDataConsumerHandle::Busy: |
| + case WebDataConsumerHandle::ResourceExhausted: |
| + case WebDataConsumerHandle::UnexpectedError: |
| + error(); |
| + return; |
| + } |
| + } |
| + } |
| + |
| + void error() |
| + { |
| + m_reader.clear(); |
| + m_rawData.clear(); |
| + m_client->didFetchDataLoadFailed(); |
| + // Here |this| might be already destructed. |
| + } |
| + |
| + LoadType m_loadType; |
| + OwnPtr<ArrayBufferBuilder> m_rawData; |
| +}; |
| + |
| +} // namespace |
| + |
| +FetchDataLoader::FetchDataLoader() |
| + : m_client(nullptr) |
| +{ |
| +} |
| + |
| +PassOwnPtr<FetchDataLoader> FetchDataLoader::createLoaderAsBlobHandle(const String& mimeType) |
| +{ |
| + return adoptPtr(new FetchDataLoaderAsBlobHandle(mimeType)); |
| +} |
| + |
| +PassOwnPtr<FetchDataLoader> FetchDataLoader::createLoaderAsArrayBuffer() |
| +{ |
| + return adoptPtr(new FetchDataLoaderAsArrayBufferOrString(FetchDataLoaderAsArrayBufferOrString::LoadAsArrayBuffer)); |
| +} |
| + |
| +PassOwnPtr<FetchDataLoader> FetchDataLoader::createLoaderAsString() |
| +{ |
| + return adoptPtr(new FetchDataLoaderAsArrayBufferOrString(FetchDataLoaderAsArrayBufferOrString::LoadAsString)); |
| +} |
| + |
| +} // namespace blink |