OLD | NEW |
---|---|
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 "modules/fetch/FetchDataLoader.h" | 5 #include "modules/fetch/FetchDataLoader.h" |
6 | 6 |
7 #include "core/html/parser/TextResourceDecoder.h" | 7 #include "core/html/parser/TextResourceDecoder.h" |
8 #include "modules/fetch/BytesConsumer.h" | |
8 #include "wtf/PtrUtil.h" | 9 #include "wtf/PtrUtil.h" |
9 #include "wtf/text/StringBuilder.h" | 10 #include "wtf/text/StringBuilder.h" |
10 #include "wtf/text/WTFString.h" | 11 #include "wtf/text/WTFString.h" |
11 #include "wtf/typed_arrays/ArrayBufferBuilder.h" | 12 #include "wtf/typed_arrays/ArrayBufferBuilder.h" |
12 #include <memory> | 13 #include <memory> |
13 | 14 |
14 namespace blink { | 15 namespace blink { |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 class FetchDataLoaderAsBlobHandle | 19 class FetchDataLoaderAsBlobHandle final : public FetchDataLoader, public BytesCo nsumer::Client { |
19 : public FetchDataLoader | 20 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsBlobHandle); |
20 , public WebDataConsumerHandle::Client { | |
21 public: | 21 public: |
22 explicit FetchDataLoaderAsBlobHandle(const String& mimeType) | 22 explicit FetchDataLoaderAsBlobHandle(const String& mimeType) |
23 : m_client(nullptr) | 23 : m_mimeType(mimeType) |
24 , m_mimeType(mimeType) { } | 24 { |
25 | 25 } |
26 DEFINE_INLINE_VIRTUAL_TRACE() | 26 |
27 { | 27 void start(BytesConsumer* consumer, FetchDataLoader::Client* client) overrid e |
28 FetchDataLoader::trace(visitor); | 28 { |
29 visitor->trace(m_client); | 29 DCHECK(!m_client); |
30 } | 30 DCHECK(!m_consumer); |
31 | 31 |
32 private: | 32 m_client = client; |
33 void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client) override | 33 m_consumer = consumer; |
34 { | 34 |
35 ASSERT(!m_client); | 35 RefPtr<BlobDataHandle> blobHandle = m_consumer->drainAsBlobDataHandle(); |
36 ASSERT(!m_reader); | |
37 | |
38 m_client = client; | |
39 // Passing |this| here is safe because |this| owns |m_reader|. | |
40 m_reader = handle->obtainFetchDataReader(this); | |
41 RefPtr<BlobDataHandle> blobHandle = m_reader->drainAsBlobDataHandle(); | |
42 if (blobHandle) { | 36 if (blobHandle) { |
43 ASSERT(blobHandle->size() != UINT64_MAX); | 37 DCHECK_NE(UINT64_MAX, blobHandle->size()); |
44 m_reader.reset(); | |
45 if (blobHandle->type() != m_mimeType) { | 38 if (blobHandle->type() != m_mimeType) { |
46 // A new BlobDataHandle is created to override the Blob's type. | 39 // A new BlobDataHandle is created to override the Blob's type. |
47 m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(bl obHandle->uuid(), m_mimeType, blobHandle->size())); | 40 m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(bl obHandle->uuid(), m_mimeType, blobHandle->size())); |
48 } else { | 41 } else { |
49 m_client->didFetchDataLoadedBlobHandle(blobHandle); | 42 m_client->didFetchDataLoadedBlobHandle(std::move(blobHandle)); |
50 } | 43 } |
51 m_client.clear(); | |
52 return; | 44 return; |
53 } | 45 } |
54 | 46 |
55 // We read data from |m_reader| and create a new blob. | |
56 m_blobData = BlobData::create(); | 47 m_blobData = BlobData::create(); |
57 m_blobData->setContentType(m_mimeType); | 48 m_blobData->setContentType(m_mimeType); |
58 } | 49 m_consumer->setClient(this); |
59 | 50 onStateChange(); |
60 void didGetReadable() override | 51 } |
61 { | 52 |
62 ASSERT(m_client); | 53 void cancel() override |
63 ASSERT(m_reader); | 54 { |
64 | 55 m_consumer->cancel(); |
65 while (true) { | 56 } |
66 const void* buffer; | 57 |
67 size_t available; | 58 void onStateChange() override |
68 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); | 59 { |
69 | 60 while (true) { |
70 switch (result) { | 61 const char* buffer; |
71 case WebDataConsumerHandle::Ok: | 62 size_t available; |
63 switch (m_consumer->beginRead(&buffer, &available)) { | |
64 case BytesConsumer::Result::Ok: | |
72 m_blobData->appendBytes(buffer, available); | 65 m_blobData->appendBytes(buffer, available); |
73 m_reader->endRead(available); | 66 m_consumer->endRead(available); |
74 break; | 67 break; |
75 | 68 case BytesConsumer::Result::ShouldWait: |
76 case WebDataConsumerHandle::Done: { | 69 return; |
77 m_reader.reset(); | 70 case BytesConsumer::Result::Done: { |
78 long long size = m_blobData->length(); | 71 auto size = m_blobData->length(); |
79 m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(st d::move(m_blobData), size)); | 72 m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(st d::move(m_blobData), size)); |
80 m_client.clear(); | 73 return; |
81 return; | 74 } |
82 } | 75 case BytesConsumer::Result::Error: |
83 | 76 m_client->didFetchDataLoadFailed(); |
84 case WebDataConsumerHandle::ShouldWait: | 77 return; |
85 return; | 78 } |
86 | 79 } |
87 case WebDataConsumerHandle::Busy: | 80 } |
88 case WebDataConsumerHandle::ResourceExhausted: | 81 |
89 case WebDataConsumerHandle::UnexpectedError: | 82 DEFINE_INLINE_TRACE() |
90 m_reader.reset(); | 83 { |
91 m_blobData.reset(); | 84 visitor->trace(m_consumer); |
92 m_client->didFetchDataLoadFailed(); | 85 visitor->trace(m_client); |
93 m_client.clear(); | 86 FetchDataLoader::trace(visitor); |
94 return; | 87 BytesConsumer::Client::trace(visitor); |
95 } | 88 } |
96 } | 89 |
97 } | 90 private: |
98 | 91 Member<BytesConsumer> m_consumer; |
99 void cancel() override | |
100 { | |
101 m_reader.reset(); | |
102 m_blobData.reset(); | |
103 m_client.clear(); | |
104 } | |
105 | |
106 std::unique_ptr<FetchDataConsumerHandle::Reader> m_reader; | |
107 Member<FetchDataLoader::Client> m_client; | 92 Member<FetchDataLoader::Client> m_client; |
108 | 93 |
109 String m_mimeType; | 94 String m_mimeType; |
110 std::unique_ptr<BlobData> m_blobData; | 95 std::unique_ptr<BlobData> m_blobData; |
111 }; | 96 }; |
112 | 97 |
113 class FetchDataLoaderAsArrayBuffer | 98 class FetchDataLoaderAsArrayBuffer final : public FetchDataLoader, public BytesC onsumer::Client { |
114 : public FetchDataLoader | 99 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsArrayBuffer) |
115 , public WebDataConsumerHandle::Client { | 100 public: |
116 public: | 101 void start(BytesConsumer* consumer, FetchDataLoader::Client* client) overrid e |
117 FetchDataLoaderAsArrayBuffer() | 102 { |
118 : m_client(nullptr) { } | 103 DCHECK(!m_client); |
119 | 104 DCHECK(!m_rawData); |
120 DEFINE_INLINE_VIRTUAL_TRACE() | 105 DCHECK(!m_consumer); |
121 { | |
122 FetchDataLoader::trace(visitor); | |
123 visitor->trace(m_client); | |
124 } | |
125 | |
126 protected: | |
127 void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client) override | |
128 { | |
129 ASSERT(!m_client); | |
130 ASSERT(!m_rawData); | |
131 ASSERT(!m_reader); | |
132 m_client = client; | 106 m_client = client; |
133 m_rawData = wrapUnique(new ArrayBufferBuilder()); | 107 m_rawData = wrapUnique(new ArrayBufferBuilder()); |
134 m_reader = handle->obtainFetchDataReader(this); | 108 m_consumer = consumer; |
135 } | 109 m_consumer->setClient(this); |
136 | 110 onStateChange(); |
137 void didGetReadable() override | 111 } |
138 { | 112 |
139 ASSERT(m_client); | 113 void cancel() override |
140 ASSERT(m_rawData); | 114 { |
141 ASSERT(m_reader); | 115 m_consumer->cancel(); |
142 | 116 } |
143 while (true) { | 117 |
144 const void* buffer; | 118 void onStateChange() override |
145 size_t available; | 119 { |
146 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); | 120 DCHECK(m_client); |
147 | 121 DCHECK(m_rawData); |
148 switch (result) { | 122 DCHECK(m_consumer); |
hiroshige
2016/08/12 08:21:17
This CL removes DCHECK(m_client) and DCHECK(m_cons
yhirano
2016/08/12 12:36:55
Done.
| |
149 case WebDataConsumerHandle::Ok: | 123 |
124 while (true) { | |
125 const char* buffer; | |
126 size_t available; | |
127 switch (m_consumer->beginRead(&buffer, &available)) { | |
128 case BytesConsumer::Result::Ok: | |
150 if (available > 0) { | 129 if (available > 0) { |
151 unsigned bytesAppended = m_rawData->append(static_cast<const char*>(buffer), available); | 130 unsigned bytesAppended = m_rawData->append(buffer, available ); |
152 if (!bytesAppended) { | 131 if (!bytesAppended) { |
153 m_reader->endRead(0); | 132 m_consumer->endRead(0); |
154 error(); | 133 m_consumer->cancel(); |
134 m_client->didFetchDataLoadFailed(); | |
155 return; | 135 return; |
156 } | 136 } |
157 ASSERT(bytesAppended == available); | 137 DCHECK_EQ(bytesAppended, available); |
158 } | 138 } |
159 m_reader->endRead(available); | 139 m_consumer->endRead(available); |
160 break; | 140 break; |
161 | 141 case BytesConsumer::Result::ShouldWait: |
162 case WebDataConsumerHandle::Done: | 142 return; |
163 m_reader.reset(); | 143 case BytesConsumer::Result::Done: |
164 m_client->didFetchDataLoadedArrayBuffer(DOMArrayBuffer::create(m _rawData->toArrayBuffer())); | 144 m_client->didFetchDataLoadedArrayBuffer(DOMArrayBuffer::create(m _rawData->toArrayBuffer())); |
165 m_rawData.reset(); | 145 return; |
166 m_client.clear(); | 146 case BytesConsumer::Result::Error: |
167 return; | 147 m_client->didFetchDataLoadFailed(); |
168 | 148 return; |
169 case WebDataConsumerHandle::ShouldWait: | 149 } |
170 return; | 150 } |
171 | 151 } |
172 case WebDataConsumerHandle::Busy: | 152 |
173 case WebDataConsumerHandle::ResourceExhausted: | 153 DEFINE_INLINE_TRACE() |
174 case WebDataConsumerHandle::UnexpectedError: | 154 { |
175 error(); | 155 visitor->trace(m_consumer); |
176 return; | 156 visitor->trace(m_client); |
177 } | 157 FetchDataLoader::trace(visitor); |
178 } | 158 BytesConsumer::Client::trace(visitor); |
179 } | 159 } |
180 | 160 |
181 void error() | 161 private: |
182 { | 162 Member<BytesConsumer> m_consumer; |
183 m_reader.reset(); | |
184 m_rawData.reset(); | |
185 m_client->didFetchDataLoadFailed(); | |
186 m_client.clear(); | |
187 } | |
188 | |
189 void cancel() override | |
190 { | |
191 m_reader.reset(); | |
192 m_rawData.reset(); | |
193 m_client.clear(); | |
194 } | |
195 | |
196 std::unique_ptr<FetchDataConsumerHandle::Reader> m_reader; | |
197 Member<FetchDataLoader::Client> m_client; | 163 Member<FetchDataLoader::Client> m_client; |
198 | 164 |
199 std::unique_ptr<ArrayBufferBuilder> m_rawData; | 165 std::unique_ptr<ArrayBufferBuilder> m_rawData; |
200 }; | 166 }; |
201 | 167 |
202 class FetchDataLoaderAsString | 168 class FetchDataLoaderAsString final : public FetchDataLoader, public BytesConsum er::Client { |
203 : public FetchDataLoader | 169 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsString); |
204 , public WebDataConsumerHandle::Client { | 170 public: |
205 public: | 171 void start(BytesConsumer* consumer, FetchDataLoader::Client* client) overrid e |
206 FetchDataLoaderAsString() | 172 { |
207 : m_client(nullptr) { } | 173 DCHECK(!m_client); |
208 | 174 DCHECK(!m_decoder); |
209 DEFINE_INLINE_VIRTUAL_TRACE() | 175 DCHECK(!m_consumer); |
210 { | |
211 FetchDataLoader::trace(visitor); | |
212 visitor->trace(m_client); | |
213 } | |
214 | |
215 protected: | |
216 void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client) override | |
217 { | |
218 ASSERT(!m_client); | |
219 ASSERT(!m_decoder); | |
220 ASSERT(!m_reader); | |
221 m_client = client; | 176 m_client = client; |
222 m_decoder = TextResourceDecoder::createAlwaysUseUTF8ForText(); | 177 m_decoder = TextResourceDecoder::createAlwaysUseUTF8ForText(); |
223 m_reader = handle->obtainFetchDataReader(this); | 178 m_consumer = consumer; |
224 } | 179 m_consumer->setClient(this); |
225 | 180 onStateChange(); |
226 void didGetReadable() override | 181 } |
227 { | 182 |
228 ASSERT(m_client); | 183 void onStateChange() override |
229 ASSERT(m_decoder); | 184 { |
230 ASSERT(m_reader); | 185 DCHECK(m_client); |
231 | 186 DCHECK(m_decoder); |
232 while (true) { | 187 DCHECK(m_consumer); |
hiroshige
2016/08/12 08:21:17
ditto.
yhirano
2016/08/12 12:36:55
Done.
| |
233 const void* buffer; | 188 |
234 size_t available; | 189 while (true) { |
235 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); | 190 const char* buffer; |
236 | 191 size_t available; |
237 switch (result) { | 192 switch (m_consumer->beginRead(&buffer, &available)) { |
238 case WebDataConsumerHandle::Ok: | 193 case BytesConsumer::Result::Ok: |
239 if (available > 0) | 194 if (available > 0) |
240 m_builder.append(m_decoder->decode(static_cast<const char*>( buffer), available)); | 195 m_builder.append(m_decoder->decode(buffer, available)); |
241 m_reader->endRead(available); | 196 m_consumer->endRead(available); |
242 break; | 197 break; |
243 | 198 case BytesConsumer::Result::ShouldWait: |
244 case WebDataConsumerHandle::Done: | 199 return; |
245 m_reader.reset(); | 200 case BytesConsumer::Result::Done: |
246 m_builder.append(m_decoder->flush()); | 201 m_builder.append(m_decoder->flush()); |
247 m_client->didFetchDataLoadedString(m_builder.toString()); | 202 m_client->didFetchDataLoadedString(m_builder.toString()); |
248 m_builder.clear(); | 203 return; |
249 m_decoder.reset(); | 204 case BytesConsumer::Result::Error: |
250 m_client.clear(); | 205 m_client->didFetchDataLoadFailed(); |
251 return; | 206 return; |
252 | 207 } |
253 case WebDataConsumerHandle::ShouldWait: | 208 } |
254 return; | |
255 | |
256 case WebDataConsumerHandle::Busy: | |
257 case WebDataConsumerHandle::ResourceExhausted: | |
258 case WebDataConsumerHandle::UnexpectedError: | |
259 error(); | |
260 return; | |
261 } | |
262 } | |
263 } | |
264 | |
265 void error() | |
266 { | |
267 m_reader.reset(); | |
268 m_builder.clear(); | |
269 m_decoder.reset(); | |
270 m_client->didFetchDataLoadFailed(); | |
271 m_client.clear(); | |
272 } | 209 } |
273 | 210 |
274 void cancel() override | 211 void cancel() override |
275 { | 212 { |
276 m_reader.reset(); | 213 m_consumer->cancel(); |
277 m_builder.clear(); | 214 } |
278 m_decoder.reset(); | 215 |
279 m_client.clear(); | 216 DEFINE_INLINE_TRACE() |
280 } | 217 { |
281 | 218 visitor->trace(m_consumer); |
282 std::unique_ptr<FetchDataConsumerHandle::Reader> m_reader; | 219 visitor->trace(m_client); |
220 FetchDataLoader::trace(visitor); | |
221 BytesConsumer::Client::trace(visitor); | |
222 } | |
223 | |
224 private: | |
225 Member<BytesConsumer> m_consumer; | |
283 Member<FetchDataLoader::Client> m_client; | 226 Member<FetchDataLoader::Client> m_client; |
284 | 227 |
285 std::unique_ptr<TextResourceDecoder> m_decoder; | 228 std::unique_ptr<TextResourceDecoder> m_decoder; |
286 StringBuilder m_builder; | 229 StringBuilder m_builder; |
287 }; | 230 }; |
288 | 231 |
289 class FetchDataLoaderAsStream | 232 class FetchDataLoaderAsStream final : public FetchDataLoader, public BytesConsum er::Client { |
290 : public FetchDataLoader | 233 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsStream); |
291 , public WebDataConsumerHandle::Client { | |
292 public: | 234 public: |
293 explicit FetchDataLoaderAsStream(Stream* outStream) | 235 explicit FetchDataLoaderAsStream(Stream* outStream) |
294 : m_client(nullptr) | 236 : m_outStream(outStream) |
295 , m_outStream(outStream) { } | 237 { |
296 | 238 } |
297 DEFINE_INLINE_VIRTUAL_TRACE() | 239 |
298 { | 240 void start(BytesConsumer* consumer, FetchDataLoader::Client* client) overrid e |
299 FetchDataLoader::trace(visitor); | 241 { |
300 visitor->trace(m_client); | 242 DCHECK(!m_client); |
301 visitor->trace(m_outStream); | 243 DCHECK(!m_consumer); |
302 } | 244 m_client = client; |
303 | 245 m_consumer = consumer; |
304 protected: | 246 m_consumer->setClient(this); |
305 void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client) override | 247 onStateChange(); |
306 { | 248 } |
307 ASSERT(!m_client); | 249 |
308 ASSERT(!m_reader); | 250 void onStateChange() override |
309 m_client = client; | 251 { |
310 m_reader = handle->obtainFetchDataReader(this); | 252 DCHECK(m_client); |
311 } | 253 DCHECK(m_consumer); |
hiroshige
2016/08/12 08:21:17
ditto.
yhirano
2016/08/12 12:36:55
Done.
| |
312 | |
313 void didGetReadable() override | |
314 { | |
315 ASSERT(m_client); | |
316 ASSERT(m_reader); | |
317 | 254 |
318 bool needToFlush = false; | 255 bool needToFlush = false; |
319 while (true) { | 256 while (true) { |
320 const void* buffer; | 257 const char* buffer; |
321 size_t available; | 258 size_t available; |
322 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); | 259 switch (m_consumer->beginRead(&buffer, &available)) { |
323 | 260 case BytesConsumer::Result::Ok: |
324 switch (result) { | 261 m_outStream->addData(buffer, available); |
325 case WebDataConsumerHandle::Ok: | 262 m_consumer->endRead(available); |
326 m_outStream->addData(static_cast<const char*>(buffer), available ); | |
327 m_reader->endRead(available); | |
328 needToFlush = true; | 263 needToFlush = true; |
329 break; | 264 break; |
330 | 265 case BytesConsumer::Result::ShouldWait: |
331 case WebDataConsumerHandle::Done: | 266 if (needToFlush) |
332 m_reader.reset(); | 267 m_outStream->flush(); |
268 return; | |
269 case BytesConsumer::Result::Done: | |
333 if (needToFlush) | 270 if (needToFlush) |
334 m_outStream->flush(); | 271 m_outStream->flush(); |
335 m_outStream->finalize(); | 272 m_outStream->finalize(); |
336 m_client->didFetchDataLoadedStream(); | 273 m_client->didFetchDataLoadedStream(); |
337 cleanup(); | 274 return; |
338 return; | 275 case BytesConsumer::Result::Error: |
339 | |
340 case WebDataConsumerHandle::ShouldWait: | |
341 if (needToFlush) | |
342 m_outStream->flush(); | |
343 return; | |
344 | |
345 case WebDataConsumerHandle::Busy: | |
346 case WebDataConsumerHandle::ResourceExhausted: | |
347 case WebDataConsumerHandle::UnexpectedError: | |
348 // If the stream is aborted soon after the stream is registered | |
349 // to the StreamRegistry, ServiceWorkerURLRequestJob may not | |
350 // notice the error and continue waiting forever. | |
351 // FIXME: Add new message to report the error to the browser | |
352 // process. | |
hiroshige
2016/08/12 08:21:17
Is this issue fixed?
yhirano
2016/08/12 12:36:55
Oops, no.
| |
353 m_reader.reset(); | |
354 m_outStream->abort(); | 276 m_outStream->abort(); |
355 m_client->didFetchDataLoadFailed(); | 277 m_client->didFetchDataLoadFailed(); |
356 cleanup(); | 278 return; |
357 return; | 279 } |
358 } | 280 } |
359 } | |
360 } | 281 } |
361 | 282 |
362 void cancel() override | 283 void cancel() override |
363 { | 284 { |
364 cleanup(); | 285 m_consumer->cancel(); |
365 } | 286 } |
366 | 287 |
367 void cleanup() | 288 DEFINE_INLINE_TRACE() |
368 { | 289 { |
369 m_reader.reset(); | 290 visitor->trace(m_consumer); |
370 m_client.clear(); | 291 visitor->trace(m_client); |
371 m_outStream.clear(); | 292 visitor->trace(m_outStream); |
293 FetchDataLoader::trace(visitor); | |
294 BytesConsumer::Client::trace(visitor); | |
372 } | 295 } |
373 | 296 |
374 std::unique_ptr<FetchDataConsumerHandle::Reader> m_reader; | 297 Member<BytesConsumer> m_consumer; |
375 Member<FetchDataLoader::Client> m_client; | 298 Member<FetchDataLoader::Client> m_client; |
376 | |
377 Member<Stream> m_outStream; | 299 Member<Stream> m_outStream; |
378 }; | 300 }; |
379 | 301 |
380 | |
381 } // namespace | 302 } // namespace |
382 | 303 |
383 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle(const String& mimeTyp e) | 304 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle(const String& mimeTyp e) |
384 { | 305 { |
385 return new FetchDataLoaderAsBlobHandle(mimeType); | 306 return new FetchDataLoaderAsBlobHandle(mimeType); |
386 } | 307 } |
387 | 308 |
388 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() | 309 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() |
389 { | 310 { |
390 return new FetchDataLoaderAsArrayBuffer(); | 311 return new FetchDataLoaderAsArrayBuffer(); |
391 } | 312 } |
392 | 313 |
393 FetchDataLoader* FetchDataLoader::createLoaderAsString() | 314 FetchDataLoader* FetchDataLoader::createLoaderAsString() |
394 { | 315 { |
395 return new FetchDataLoaderAsString(); | 316 return new FetchDataLoaderAsString(); |
396 } | 317 } |
397 | 318 |
398 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) | 319 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) |
399 { | 320 { |
400 return new FetchDataLoaderAsStream(outStream); | 321 return new FetchDataLoaderAsStream(outStream); |
401 } | 322 } |
402 | 323 |
403 } // namespace blink | 324 } // namespace blink |
OLD | NEW |