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

Side by Side Diff: third_party/WebKit/Source/core/streams/ReadableStreamImpl.h

Issue 2227403002: Remove blink::ReadableStream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 4 years, 4 months 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
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef ReadableStreamImpl_h
6 #define ReadableStreamImpl_h
7
8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptPromise.h"
10 #include "bindings/core/v8/ScriptPromiseResolver.h"
11 #include "bindings/core/v8/ScriptState.h"
12 #include "bindings/core/v8/ScriptValue.h"
13 #include "bindings/core/v8/ToV8.h"
14 #include "bindings/core/v8/V8ArrayBuffer.h"
15 #include "bindings/core/v8/V8Binding.h"
16 #include "bindings/core/v8/V8IteratorResultValue.h"
17 #include "core/dom/DOMArrayBuffer.h"
18 #include "core/dom/DOMArrayBufferView.h"
19 #include "core/dom/DOMException.h"
20 #include "core/streams/ReadableStream.h"
21 #include "wtf/Deque.h"
22 #include "wtf/RefPtr.h"
23 #include "wtf/text/WTFString.h"
24 #include <utility>
25
26 namespace blink {
27
28 // We define the default ChunkTypeTraits for frequently used types.
29 template<typename ChunkType>
30 class ReadableStreamChunkTypeTraits {
31 STATIC_ONLY(ReadableStreamChunkTypeTraits);
32 };
33
34 template<>
35 class ReadableStreamChunkTypeTraits<String> {
36 public:
37 typedef String HoldType;
38 typedef const String& PassType;
39
40 static size_t size(const String& chunk) { return chunk.length(); }
41 static ScriptValue toScriptValue(ScriptState* scriptState, const HoldType& v alue)
42 {
43 return ScriptValue(scriptState, v8String(scriptState->isolate(), value)) ;
44 }
45 };
46
47 template<>
48 class ReadableStreamChunkTypeTraits<DOMArrayBuffer> {
49 public:
50 typedef DOMArrayBuffer* HoldType;
51 typedef DOMArrayBuffer* PassType;
52
53 static size_t size(const PassType& chunk) { return chunk->byteLength(); }
54 static ScriptValue toScriptValue(ScriptState* scriptState, const HoldType& v alue)
55 {
56 return ScriptValue(scriptState, toV8(value, scriptState->context()->Glob al(), scriptState->isolate()));
57 }
58 };
59
60 template<>
61 class ReadableStreamChunkTypeTraits<DOMArrayBufferView> {
62 public:
63 typedef DOMArrayBufferView* HoldType;
64 typedef DOMArrayBufferView* PassType;
65
66 static size_t size(const PassType& chunk) { return chunk->byteLength(); }
67 static ScriptValue toScriptValue(ScriptState* scriptState, const HoldType& v alue)
68 {
69 return ScriptValue(scriptState, toV8(value, scriptState->context()->Glob al(), scriptState->isolate()));
70 }
71 };
72
73 // ReadableStreamImpl<ChunkTypeTraits> is a ReadableStream subtype. It has a
74 // queue whose type depends on ChunkTypeTraits and it implements queue-related
75 // ReadableStream pure virtual methods.
76 template <typename ChunkTypeTraits>
77 class ReadableStreamImpl : public ReadableStream {
78 public:
79 class Strategy : public GarbageCollectedFinalized<Strategy> {
80 public:
81 virtual ~Strategy() { }
82
83 // These functions call ReadableStream::error on error.
84 virtual size_t size(const typename ChunkTypeTraits::PassType& chunk, Rea dableStream*) { return ChunkTypeTraits::size(chunk); }
85 virtual bool shouldApplyBackpressure(size_t totalQueueSize, ReadableStre am*) = 0;
86
87 DEFINE_INLINE_VIRTUAL_TRACE() { }
88 };
89
90 class DefaultStrategy : public Strategy {
91 public:
92 size_t size(const typename ChunkTypeTraits::PassType& chunk, ReadableStr eam*) override { return 1; }
93 bool shouldApplyBackpressure(size_t totalQueueSize, ReadableStream*) ove rride { return totalQueueSize > 1; }
94 };
95
96 class StrictStrategy : public Strategy {
97 public:
98 size_t size(const typename ChunkTypeTraits::PassType& chunk, ReadableStr eam*) override { return 1; }
99 bool shouldApplyBackpressure(size_t totalQueueSize, ReadableStream*) ove rride { return true; }
100 };
101
102 explicit ReadableStreamImpl(UnderlyingSource* source)
103 : ReadableStreamImpl(source, new DefaultStrategy) { }
104 ReadableStreamImpl(UnderlyingSource* source, Strategy* strategy)
105 : ReadableStream(source)
106 , m_strategy(strategy)
107 , m_totalQueueSize(0) { }
108 ~ReadableStreamImpl() override { }
109
110 // ReadableStream methods
111 ScriptPromise read(ScriptState*) override;
112
113 bool enqueue(typename ChunkTypeTraits::PassType);
114
115 // This function is intended to be used by internal code to withdraw
116 // queued data. This pulls all data from this stream's queue, but
117 // ReadableStream public APIs can work with the behavior (i.e. it behaves
118 // as if multiple read-one-buffer calls were made).
119 void readInternal(Deque<std::pair<typename ChunkTypeTraits::HoldType, size_t >>& queue);
120
121 DEFINE_INLINE_VIRTUAL_TRACE()
122 {
123 visitor->trace(m_strategy);
124 visitor->trace(m_pendingReads);
125 ReadableStream::trace(visitor);
126 }
127
128 private:
129 using PendingReads = HeapDeque<Member<ScriptPromiseResolver>>;
130
131 // ReadableStream methods
132 bool isQueueEmpty() const override { return m_queue.isEmpty(); }
133 void clearQueue() override
134 {
135 m_queue.clear();
136 m_totalQueueSize = 0;
137 }
138
139 void resolveAllPendingReadsAsDone() override
140 {
141 for (auto& resolver : m_pendingReads) {
142 ScriptState* scriptState = resolver->getScriptState();
143 if (!scriptState->contextIsValid())
144 continue;
145 ScriptState::Scope scope(scriptState);
146 resolver->resolve(v8IteratorResultDone(scriptState));
147 }
148 m_pendingReads.clear();
149 }
150
151 void rejectAllPendingReads(DOMException* reason) override
152 {
153 for (auto& resolver : m_pendingReads)
154 resolver->reject(reason);
155 m_pendingReads.clear();
156 }
157
158 bool shouldApplyBackpressure() override
159 {
160 return m_strategy->shouldApplyBackpressure(m_totalQueueSize, this);
161 }
162 bool hasPendingReads() const override { return !m_pendingReads.isEmpty(); }
163
164 Member<Strategy> m_strategy;
165 Deque<std::pair<typename ChunkTypeTraits::HoldType, size_t>> m_queue;
166 PendingReads m_pendingReads;
167 size_t m_totalQueueSize;
168 };
169
170 template <typename ChunkTypeTraits>
171 bool ReadableStreamImpl<ChunkTypeTraits>::enqueue(typename ChunkTypeTraits::Pass Type chunk)
172 {
173 size_t size = m_strategy->size(chunk, this);
174 if (!enqueuePreliminaryCheck())
175 return false;
176
177 if (m_pendingReads.isEmpty()) {
178 m_queue.append(std::make_pair(chunk, size));
179 m_totalQueueSize += size;
180 return enqueuePostAction();
181 }
182
183 ScriptPromiseResolver* resolver = m_pendingReads.takeFirst();
184 ScriptState* scriptState = resolver->getScriptState();
185 if (!scriptState->contextIsValid())
186 return false;
187 ScriptState::Scope scope(scriptState);
188 resolver->resolve(v8IteratorResult(scriptState, chunk));
189 return enqueuePostAction();
190 }
191
192 template <typename ChunkTypeTraits>
193 ScriptPromise ReadableStreamImpl<ChunkTypeTraits>::read(ScriptState* scriptState )
194 {
195 if (stateInternal() == Closed)
196 return ScriptPromise::cast(scriptState, v8IteratorResultDone(scriptState ));
197 if (stateInternal() == Errored)
198 return ScriptPromise::reject(scriptState, toV8(storedException(), script State->context()->Global(), scriptState->isolate()));
199
200 ASSERT(stateInternal() == Readable);
201 setIsDisturbed();
202 if (m_queue.isEmpty()) {
203 m_pendingReads.append(ScriptPromiseResolver::create(scriptState));
204 ScriptPromise promise = m_pendingReads.last()->promise();
205 readInternalPostAction();
206 return promise;
207 }
208
209 auto pair = m_queue.takeFirst();
210 typename ChunkTypeTraits::HoldType chunk = pair.first;
211 size_t size = pair.second;
212 ASSERT(m_totalQueueSize >= size);
213 m_totalQueueSize -= size;
214 readInternalPostAction();
215
216 return ScriptPromise::cast(scriptState, v8IteratorResult(scriptState, chunk) );
217 }
218
219 template <typename ChunkTypeTraits>
220 void ReadableStreamImpl<ChunkTypeTraits>::readInternal(Deque<std::pair<typename ChunkTypeTraits::HoldType, size_t>>& queue)
221 {
222 // We omit the preliminary check. Check it by yourself.
223 ASSERT(stateInternal() == Readable);
224 ASSERT(m_pendingReads.isEmpty());
225 ASSERT(queue.isEmpty());
226
227 setIsDisturbed();
228 queue.swap(m_queue);
229 m_totalQueueSize = 0;
230 readInternalPostAction();
231 }
232
233 } // namespace blink
234
235 #endif // ReadableStreamImpl_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698