Chromium Code Reviews| Index: Source/core/streams/ReadableStream.cpp |
| diff --git a/Source/core/streams/ReadableStream.cpp b/Source/core/streams/ReadableStream.cpp |
| index 0f1a80cf61547873af993ab1d7c6070e855e8280..061b9b942ef26373be56271cfeb5178e34af2761 100644 |
| --- a/Source/core/streams/ReadableStream.cpp |
| +++ b/Source/core/streams/ReadableStream.cpp |
| @@ -12,6 +12,7 @@ |
| #include "core/dom/DOMException.h" |
| #include "core/dom/ExceptionCode.h" |
| #include "core/dom/ExecutionContext.h" |
| +#include "core/streams/ExclusiveStreamReader.h" |
| #include "core/streams/UnderlyingSource.h" |
| namespace blink { |
| @@ -33,6 +34,32 @@ private: |
| } |
| }; |
| +class ResolveWithReady : public ScriptFunction { |
| +public: |
| + static v8::Handle<v8::Function> create(ScriptState* scriptState, ReadableStream* stream) |
| + { |
| + return (new ResolveWithReady(scriptState, stream))->bindToV8Function(); |
| + } |
| + |
| + void trace(Visitor* visitor) |
| + { |
| + visitor->trace(m_stream); |
| + ScriptFunction::trace(visitor); |
| + } |
| + |
| +private: |
| + ResolveWithReady(ScriptState* scriptState, ReadableStream* stream) |
| + : ScriptFunction(scriptState) |
| + , m_stream(stream) { } |
| + |
| + ScriptValue call(ScriptValue value) override |
| + { |
| + return ScriptValue(scriptState(), m_stream->ready(scriptState()).v8Value()); |
| + } |
| + |
| + Member<ReadableStream> m_stream; |
| +}; |
| + |
| } // namespace |
| ReadableStream::ReadableStream(ExecutionContext* executionContext, UnderlyingSource* source) |
| @@ -54,18 +81,10 @@ ReadableStream::~ReadableStream() |
| String ReadableStream::stateString() const |
| { |
| - switch (m_state) { |
| - case Readable: |
| - return "readable"; |
| - case Waiting: |
| + if (m_reader) |
| return "waiting"; |
| - case Closed: |
| - return "closed"; |
| - case Errored: |
| - return "errored"; |
| - } |
| - ASSERT(false); |
| - return String(); |
| + |
| + return stateToString(m_state); |
| } |
| bool ReadableStream::enqueuePreliminaryCheck() |
| @@ -108,13 +127,15 @@ void ReadableStream::close() |
| if (m_state == Waiting) { |
| m_ready->resolve(ToV8UndefinedGenerator()); |
| m_closed->resolve(ToV8UndefinedGenerator()); |
| + if (m_reader) |
| + m_reader->releaseLock(); |
| m_state = Closed; |
| } else if (m_state == Readable) { |
| m_isDraining = true; |
| } |
| } |
| -void ReadableStream::readPreliminaryCheck(ExceptionState& exceptionState) |
| +void ReadableStream::readInternalPreliminaryCheck(ExceptionState& exceptionState) |
| { |
| if (m_state == Waiting) { |
| exceptionState.throwTypeError("read is called while state is waiting"); |
| @@ -130,12 +151,14 @@ void ReadableStream::readPreliminaryCheck(ExceptionState& exceptionState) |
| } |
| } |
| -void ReadableStream::readPostAction() |
| +void ReadableStream::readInternalPostAction() |
| { |
| ASSERT(m_state == Readable); |
| if (isQueueEmpty()) { |
| if (m_isDraining) { |
| m_closed->resolve(ToV8UndefinedGenerator()); |
| + if (m_reader) |
| + m_reader->releaseLock(); |
| m_state = Closed; |
|
tyoshino (SeeGerritForStatus)
2015/02/02 08:38:24
this doesn't cause any real issue, but let's updat
yhirano
2015/02/02 10:21:20
Done.
|
| } else { |
| m_ready->reset(); |
| @@ -145,13 +168,36 @@ void ReadableStream::readPostAction() |
| callPullIfNeeded(); |
| } |
| +ScriptValue ReadableStream::read(ScriptState* scriptState, ExceptionState& exceptionState) |
| +{ |
| + if (m_reader) { |
| + exceptionState.throwTypeError("this stream is locked to an ExclusiveStreamReader"); |
| + return ScriptValue(); |
| + } |
| + return readInternal(scriptState, exceptionState); |
| +} |
| + |
| ScriptPromise ReadableStream::ready(ScriptState* scriptState) |
| { |
| + if (m_reader) { |
| + return m_reader->released(scriptState).then(ResolveWithReady::create(scriptState, this)); |
| + } |
| + |
| + if (m_state == Waiting) { |
| + return readyInternal(scriptState).then(ResolveWithReady::create(scriptState, this)); |
| + } |
| + return readyInternal(scriptState); |
| +} |
| + |
| +ScriptPromise ReadableStream::readyInternal(ScriptState* scriptState) |
| +{ |
| return m_ready->promise(scriptState->world()); |
| } |
| ScriptPromise ReadableStream::cancel(ScriptState* scriptState, ScriptValue reason) |
| { |
| + if (m_reader) |
| + return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "this stream is locked to an ExclusiveStreamReader")); |
| if (m_state == Closed) |
| return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
| if (m_state == Errored) |
| @@ -179,6 +225,8 @@ void ReadableStream::error(PassRefPtrWillBeRawPtr<DOMException> exception) |
| m_ready->reject(m_exception); |
| m_closed->reject(m_exception); |
| m_state = Errored; |
| + if (m_reader) |
| + m_reader->releaseLock(); |
| break; |
| case Readable: |
| clearQueue(); |
| @@ -187,6 +235,8 @@ void ReadableStream::error(PassRefPtrWillBeRawPtr<DOMException> exception) |
| m_ready->reject(m_exception); |
| m_closed->reject(m_exception); |
| m_state = Errored; |
| + if (m_reader) |
| + m_reader->releaseLock(); |
| break; |
| default: |
| break; |
| @@ -199,6 +249,21 @@ void ReadableStream::didSourceStart() |
| callPullIfNeeded(); |
| } |
| +ExclusiveStreamReader* ReadableStream::getReader(ExceptionState& exceptionState) |
| +{ |
| + if (m_reader) { |
| + exceptionState.throwTypeError("already locked to an ExclusiveStreamReader"); |
| + return nullptr; |
| + } |
|
tyoshino (SeeGerritForStatus)
2015/02/02 08:38:24
Throw for closed and errored stream as specified i
yhirano
2015/02/02 10:21:20
Done.
|
| + return new ExclusiveStreamReader(this); |
| +} |
| + |
| +void ReadableStream::setReader(ExclusiveStreamReader* reader) |
| +{ |
| + ASSERT((reader && !m_reader) || (!reader && m_reader)); |
| + m_reader = reader; |
| +} |
| + |
| void ReadableStream::callPullIfNeeded() |
| { |
| if (m_isPulling || m_isDraining || !m_isStarted || m_state == Closed || m_state == Errored) |
| @@ -223,7 +288,24 @@ void ReadableStream::trace(Visitor* visitor) |
| visitor->trace(m_ready); |
| visitor->trace(m_closed); |
| visitor->trace(m_exception); |
| + visitor->trace(m_reader); |
| ActiveDOMObject::trace(visitor); |
| } |
| +String ReadableStream::stateToString(State state) |
| +{ |
| + switch (state) { |
| + case Readable: |
| + return "readable"; |
| + case Waiting: |
| + return "waiting"; |
| + case Closed: |
| + return "closed"; |
| + case Errored: |
| + return "errored"; |
| + } |
| + ASSERT(false); |
| + return String(); |
| +} |
| + |
| } // namespace blink |