Chromium Code Reviews| Index: third_party/WebKit/Source/modules/fetch/Body.cpp |
| diff --git a/third_party/WebKit/Source/modules/fetch/Body.cpp b/third_party/WebKit/Source/modules/fetch/Body.cpp |
| index 1e64fe123a83319bc00f9ea7a453c3a6c61a3caa..6e0d6c8e23c9c6374e1cb0a0ab438e206f8445a9 100644 |
| --- a/third_party/WebKit/Source/modules/fetch/Body.cpp |
| +++ b/third_party/WebKit/Source/modules/fetch/Body.cpp |
| @@ -14,8 +14,13 @@ |
| #include "core/dom/ExceptionCode.h" |
| #include "core/fileapi/Blob.h" |
| #include "core/frame/UseCounter.h" |
| +#include "core/streams/ReadableStreamController.h" |
| +#include "core/streams/ReadableStreamOperations.h" |
| +#include "core/streams/UnderlyingSourceBase.h" |
| #include "modules/fetch/BodyStreamBuffer.h" |
| #include "modules/fetch/FetchDataLoader.h" |
| +#include "public/platform/WebDataConsumerHandle.h" |
| +#include "wtf/OwnPtr.h" |
| #include "wtf/PassRefPtr.h" |
| #include "wtf/RefPtr.h" |
| @@ -99,6 +104,59 @@ public: |
| } |
| }; |
| +class UnderlyingSourceFromDataConsumerHandle final : public UnderlyingSourceBase, public WebDataConsumerHandle::Client { |
| + EAGERLY_FINALIZE(); |
| + DECLARE_EAGER_FINALIZATION_OPERATOR_NEW(); |
|
sof
2016/04/04 11:26:32
this derived class looks fine & macro is needed as
|
| +public: |
| + UnderlyingSourceFromDataConsumerHandle(ScriptState* scriptState, PassOwnPtr<WebDataConsumerHandle> handle) |
| + : UnderlyingSourceBase(scriptState) |
| + , m_scriptState(scriptState) |
| + , m_reader(handle->obtainReader(this)) |
| + { |
| + } |
| + |
| + ScriptPromise pull(ScriptState* scriptState) override |
| + { |
| + didGetReadable(); |
| + return ScriptPromise::castUndefined(scriptState); |
| + } |
| + |
| + ScriptPromise cancel(ScriptState* scriptState, ScriptValue reason) override |
| + { |
| + m_reader = nullptr; |
| + return ScriptPromise::castUndefined(scriptState); |
| + } |
| + |
| + void didGetReadable() override |
| + { |
| + while (controller()->desiredSize() > 0) { |
| + size_t available; |
|
sof
2016/04/04 11:26:32
Don't you risk running into "potentially uninitial
yhirano
2016/04/04 11:42:32
Done.
|
| + const void* buffer = nullptr; |
| + WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); |
| + if (result == WebDataConsumerHandle::Ok) { |
| + RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::create(available, 1); |
| + memcpy(arrayBuffer->data(), buffer, available); |
| + m_reader->endRead(available); |
| + controller()->enqueue(DOMUint8Array::create(arrayBuffer.release(), 0, available)); |
| + } else if (result == WebDataConsumerHandle::ShouldWait) { |
| + break; |
| + } else if (result == WebDataConsumerHandle::Done) { |
| + m_reader = nullptr; |
| + controller()->close(); |
| + break; |
| + } else { |
| + m_reader = nullptr; |
| + controller()->error(V8ThrowException::createTypeError(m_scriptState->isolate(), "Network error")); |
| + break; |
| + } |
| + } |
| + } |
| + |
| +private: |
| + RefPtr<ScriptState> m_scriptState; |
| + OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
| +}; |
| + |
| } // namespace |
| ScriptPromise Body::arrayBuffer(ScriptState* scriptState) |
| @@ -200,6 +258,16 @@ ReadableByteStream* Body::bodyWithUseCounter() |
| return body(); |
| } |
| +ScriptValue Body::v8ExtraStreamBody(ScriptState* scriptState) |
| +{ |
| + if (bodyUsed() || isBodyLocked() || !bodyBuffer()) |
| + return ScriptValue(scriptState, v8::Undefined(scriptState->isolate())); |
| + OwnPtr<FetchDataConsumerHandle> handle = bodyBuffer()->releaseHandle(scriptState->getExecutionContext()); |
| + return ReadableStreamOperations::createReadableStream(scriptState, |
| + new UnderlyingSourceFromDataConsumerHandle(scriptState, handle.release()), |
| + ScriptValue(scriptState, v8::Undefined(scriptState->isolate()))); |
| +} |
| + |
| bool Body::bodyUsed() |
| { |
| return body() && body()->isDisturbed(); |