1c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// found in the LICENSE file. 4c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 5c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "config.h" 6c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/streams/ReadableStream.h" 7c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 8c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "bindings/core/v8/ExceptionState.h" 9c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "bindings/core/v8/ScriptFunction.h" 10c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "bindings/core/v8/ScriptPromiseResolver.h" 11c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "bindings/core/v8/V8Binding.h" 12c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/dom/DOMException.h" 13c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/dom/ExceptionCode.h" 14c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/dom/ExecutionContext.h" 15c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/streams/UnderlyingSource.h" 16c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 17c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 18c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 199e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)ReadableStream::ReadableStream(ExecutionContext* executionContext, UnderlyingSource* source) 209e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) : m_source(source) 21c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_isStarted(false) 22c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_isDraining(false) 23c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_isPulling(false) 24c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_isSchedulingPull(false) 25c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_state(Waiting) 269e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) , m_wait(new WaitPromise(executionContext, this, WaitPromise::Ready)) 279e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) , m_closed(new ClosedPromise(executionContext, this, ClosedPromise::Closed)) 28c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 30c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 31c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ReadableStream::~ReadableStream() 32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 34c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 359e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)String ReadableStream::stateString() const 369e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){ 379e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) switch (m_state) { 389e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) case Readable: 399e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return "readable"; 409e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) case Waiting: 419e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return "waiting"; 429e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) case Closed: 439e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return "closed"; 449e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) case Errored: 459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return "errored"; 469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) } 479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) ASSERT(false); 489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return String(); 499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)} 509e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) 51e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)bool ReadableStream::enqueuePreliminaryCheck(size_t chunkSize) 52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Errored || m_state == Closed || m_isDraining) 54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return false; 55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // FIXME: Query strategy. 57e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return true; 58e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} 59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 60e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)bool ReadableStream::enqueuePostAction(size_t totalQueueSize) 61e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){ 62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_isPulling = false; 63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // FIXME: Set needsMore correctly. 65c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) bool needsMore = true; 66c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Waiting) { 68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_state = Readable; 69e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->resolve(V8UndefinedType()); 70c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 71c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 72c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return needsMore; 73c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 75c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ReadableStream::close() 76c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 77c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Waiting) { 78e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->resolve(V8UndefinedType()); 79c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_closed->resolve(V8UndefinedType()); 80c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_state = Closed; 81c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } else if (m_state == Readable) { 82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_isDraining = true; 83c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 869e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void ReadableStream::readPreliminaryCheck(ExceptionState& exceptionState) 87c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Waiting) { 899e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) exceptionState.throwTypeError("read is called while state is waiting"); 90e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return; 91c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Closed) { 939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) exceptionState.throwTypeError("read is called while state is closed"); 94e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return; 95c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Errored) { 979e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) exceptionState.throwDOMException(m_exception->code(), m_exception->message()); 98e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return; 99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 100e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} 101c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 102e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void ReadableStream::readPostAction() 103e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){ 104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_state == Readable); 105e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) if (isQueueEmpty()) { 106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_isDraining) { 107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_state = Closed; 108e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->reset(); 109e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->resolve(V8UndefinedType()); 110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_closed->resolve(V8UndefinedType()); 111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } else { 112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_state = Waiting; 113e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->reset(); 114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) callOrSchedulePull(); 115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 119c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptPromise ReadableStream::wait(ScriptState* scriptState) 120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Waiting) 122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) callOrSchedulePull(); 123c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return m_wait->promise(scriptState->world()); 124c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 126c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptPromise ReadableStream::cancel(ScriptState* scriptState, ScriptValue reason) 127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Errored) { 129c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); 130c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ScriptPromise promise = resolver->promise(); 131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) resolver->reject(m_exception); 132c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return promise; 133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Closed) 135c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); 136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Waiting) { 138e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->resolve(V8UndefinedType()); 139c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } else { 140c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_state == Readable); 141e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->reset(); 142e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->resolve(V8UndefinedType()); 143c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 144c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 145e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) clearQueue(); 146c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_state = Closed; 147c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_closed->resolve(V8UndefinedType()); 148c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return m_source->cancelSource(scriptState, reason); 149c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 150c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 151c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptPromise ReadableStream::closed(ScriptState* scriptState) 152c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 153c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return m_closed->promise(scriptState->world()); 154c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 155c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 156c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ReadableStream::error(PassRefPtrWillBeRawPtr<DOMException> exception) 157c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 158c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Readable) { 159e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) clearQueue(); 160e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) m_wait->reset(); 161c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 162c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 163c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_state == Waiting || m_state == Readable) { 164c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_state = Errored; 165c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_exception = exception; 166c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_wait->state() == m_wait->Pending) 167c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_wait->reject(m_exception); 168c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_closed->reject(m_exception); 169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 170c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 171c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 1729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void ReadableStream::didSourceStart() 173c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 174c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_isStarted = true; 175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_isSchedulingPull) 176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_source->pullSource(); 177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 178c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 179c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ReadableStream::callOrSchedulePull() 180c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 181c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_isPulling) 182c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return; 183c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_isPulling = true; 184c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_isStarted) 185c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_source->pullSource(); 186c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) else 187c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_isSchedulingPull = true; 188c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 189c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 190c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ReadableStream::trace(Visitor* visitor) 191c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 192c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) visitor->trace(m_source); 193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) visitor->trace(m_wait); 194c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) visitor->trace(m_closed); 195c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) visitor->trace(m_exception); 196c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 198c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 199c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 200