Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/WebKit/Source/core/streams/ReadableStreamReader.cpp

Issue 1418813004: [Fetch API] Reflect spec changes of bodyUsed property (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/streams/ReadableStreamReader.h" 6 #include "core/streams/ReadableStreamReader.h"
7 7
8 #include "bindings/core/v8/ExceptionState.h" 8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "bindings/core/v8/ToV8.h"
10 #include "bindings/core/v8/V8IteratorResultValue.h" 11 #include "bindings/core/v8/V8IteratorResultValue.h"
11 #include "core/dom/DOMException.h" 12 #include "core/dom/DOMException.h"
12 #include "core/dom/ExceptionCode.h" 13 #include "core/dom/ExceptionCode.h"
13 #include "core/streams/ReadableStream.h" 14 #include "core/streams/ReadableStream.h"
14 15
15 namespace blink { 16 namespace blink {
16 17
17 ReadableStreamReader::ReadableStreamReader(ExecutionContext* executionContext, R eadableStream* stream) 18 ReadableStreamReader::ReadableStreamReader(ExecutionContext* executionContext, R eadableStream* stream)
18 : ActiveDOMObject(executionContext) 19 : ActiveDOMObject(executionContext)
19 , m_stream(stream) 20 , m_stream(stream)
20 , m_stateAfterRelease(ReadableStream::Closed)
21 , m_closed(new ClosedPromise(executionContext, this, ClosedPromise::Closed)) 21 , m_closed(new ClosedPromise(executionContext, this, ClosedPromise::Closed))
22 { 22 {
23 suspendIfNeeded(); 23 suspendIfNeeded();
24 ASSERT(m_stream->isLockedTo(nullptr)); 24 ASSERT(m_stream->isLockedTo(nullptr));
25 m_stream->setReader(this); 25 m_stream->setReader(this);
26 26
27 if (m_stream->stateInternal() == ReadableStream::Closed || m_stream->stateIn ternal() == ReadableStream::Errored) { 27 if (m_stream->stateInternal() == ReadableStream::Closed)
28 // If the stream is already closed or errored the created reader 28 m_closed->resolve(ToV8UndefinedGenerator());
29 // should be closed or errored respectively. 29 if (m_stream->stateInternal() == ReadableStream::Errored)
30 releaseLock(); 30 m_closed->reject(m_stream->storedException());
31 }
32 } 31 }
33 32
34 ScriptPromise ReadableStreamReader::closed(ScriptState* scriptState) 33 ScriptPromise ReadableStreamReader::closed(ScriptState* scriptState)
35 { 34 {
36 return m_closed->promise(scriptState->world()); 35 return m_closed->promise(scriptState->world());
37 } 36 }
38 37
39 bool ReadableStreamReader::isActive() const 38 bool ReadableStreamReader::isActive() const
40 { 39 {
41 return m_stream->isLockedTo(this); 40 return m_stream->isLockedTo(this);
42 } 41 }
43 42
44 ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState) 43 ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState)
45 { 44 {
46 return cancel(scriptState, ScriptValue(scriptState, v8::Undefined(scriptStat e->isolate()))); 45 return cancel(scriptState, ScriptValue(scriptState, v8::Undefined(scriptStat e->isolate())));
47 } 46 }
48 47
49 ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState, ScriptValue reason) 48 ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState, ScriptValue reason)
50 { 49 {
51 if (isActive()) 50 if (isActive())
52 return m_stream->cancelInternal(scriptState, reason); 51 return m_stream->cancelInternal(scriptState, reason);
53 52
54 // A method should return a different promise on each call. 53 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError( scriptState->isolate(), "the reader is already released"));
55 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
56 ScriptPromise promise = resolver->promise();
57 resolver->resolve(closed(scriptState).v8Value());
58 return promise;
59 } 54 }
60 55
61 ScriptPromise ReadableStreamReader::read(ScriptState* scriptState) 56 ScriptPromise ReadableStreamReader::read(ScriptState* scriptState)
62 { 57 {
63 if (!isActive()) { 58 if (!isActive())
64 ASSERT(m_stateAfterRelease == ReadableStream::Closed || m_stateAfterRele ase == ReadableStream::Errored); 59 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "the reader is already released"));
65 if (m_stateAfterRelease == ReadableStream::Closed) {
66 // {value: undefined, done: true}
67 return ScriptPromise::cast(scriptState, v8IteratorResultDone(scriptS tate));
68 }
69 // A method should return a different promise on each call.
70 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptSt ate);
71 ScriptPromise promise = resolver->promise();
72 resolver->resolve(closed(scriptState).v8Value());
73 return promise;
74 }
75 60
76 return m_stream->read(scriptState); 61 return m_stream->read(scriptState);
77 } 62 }
78 63
79 void ReadableStreamReader::releaseLock(ExceptionState& es) 64 void ReadableStreamReader::releaseLock(ExceptionState& es)
80 { 65 {
81 if (!isActive()) 66 if (!isActive())
82 return; 67 return;
83 if (m_stream->hasPendingReads()) { 68 if (m_stream->hasPendingReads()) {
84 es.throwTypeError("The stream has pending read operations."); 69 es.throwTypeError("The stream has pending read operations.");
85 return; 70 return;
86 } 71 }
87 72
88 releaseLock(); 73 releaseLock();
89 } 74 }
90 75
91 void ReadableStreamReader::releaseLock() 76 void ReadableStreamReader::releaseLock()
92 { 77 {
93 if (!isActive()) 78 if (!isActive())
94 return; 79 return;
95 80
96 ASSERT(!m_stream->hasPendingReads()); 81 ASSERT(!m_stream->hasPendingReads());
97 if (m_stream->stateInternal() == ReadableStream::Closed) { 82 if (m_stream->stateInternal() != ReadableStream::Readable)
98 m_stateAfterRelease = ReadableStream::Closed; 83 m_closed->reset();
99 m_closed->resolve(ToV8UndefinedGenerator()); 84 // Note: It is generally a bad idea to store world-dependent values
100 } else if (m_stream->stateInternal() == ReadableStream::Errored) { 85 // (e.g. v8::Object) in a ScriptPromiseProperty, so we use DOMException
101 m_stateAfterRelease = ReadableStream::Errored; 86 // though the spec says the promise should be rejected with a TypeError.
102 m_closed->reject(m_stream->storedException()); 87 m_closed->reject(DOMException::create(AbortError, "the reader is already rel eased"));
103 } else {
104 m_stateAfterRelease = ReadableStream::Closed;
105 m_closed->resolve(ToV8UndefinedGenerator());
106 }
107 88
108 // We call setReader(nullptr) after resolving / rejecting |m_closed| 89 // We call setReader(nullptr) after resolving / rejecting |m_closed|
109 // because it affects hasPendingActivity. 90 // because it affects hasPendingActivity.
110 m_stream->setReader(nullptr); 91 m_stream->setReader(nullptr);
111 ASSERT(!isActive()); 92 ASSERT(!isActive());
112 } 93 }
113 94
95 void ReadableStreamReader::close()
96 {
97 ASSERT(isActive());
98 m_closed->resolve(ToV8UndefinedGenerator());
99 }
100
101 void ReadableStreamReader::error()
102 {
103 ASSERT(isActive());
104 m_closed->reject(m_stream->storedException());
105 }
106
114 bool ReadableStreamReader::hasPendingActivity() const 107 bool ReadableStreamReader::hasPendingActivity() const
115 { 108 {
116 // We need to extend ReadableStreamReader's wrapper's life while it is 109 // We need to extend ReadableStreamReader's wrapper's life while it is
117 // active in order to call resolve / reject on ScriptPromiseProperties. 110 // active in order to call resolve / reject on ScriptPromiseProperties.
118 return isActive(); 111 return isActive() && m_stream->stateInternal() == ReadableStream::Readable;
119 } 112 }
120 113
121 void ReadableStreamReader::stop() 114 void ReadableStreamReader::stop()
122 { 115 {
123 if (isActive()) { 116 if (isActive()) {
124 // Calling |error| will release the lock. 117 // Calling |error| will release the lock.
125 m_stream->error(DOMException::create(AbortError, "The frame stops workin g.")); 118 m_stream->error(DOMException::create(AbortError, "The frame stops workin g."));
126 } 119 }
127 ActiveDOMObject::stop(); 120 ActiveDOMObject::stop();
128 } 121 }
129 122
130 DEFINE_TRACE(ReadableStreamReader) 123 DEFINE_TRACE(ReadableStreamReader)
131 { 124 {
132 visitor->trace(m_stream); 125 visitor->trace(m_stream);
133 visitor->trace(m_closed); 126 visitor->trace(m_closed);
134 ActiveDOMObject::trace(visitor); 127 ActiveDOMObject::trace(visitor);
135 } 128 }
136 129
137 } // namespace blink 130 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698