| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 #include "modules/fetch/FetchDataLoader.h" |
| 7 |
| 8 #include "wtf/ArrayBufferBuilder.h" |
| 9 #include "wtf/text/WTFString.h" |
| 10 |
| 11 namespace blink { |
| 12 |
| 13 namespace { |
| 14 |
| 15 class FetchDataLoaderAsBlobHandle |
| 16 : public FetchDataLoader |
| 17 , public WebDataConsumerHandle::Client { |
| 18 public: |
| 19 explicit FetchDataLoaderAsBlobHandle(const String& mimeType) |
| 20 : m_client(nullptr) |
| 21 , m_mimeType(mimeType) { } |
| 22 |
| 23 DEFINE_INLINE_VIRTUAL_TRACE() |
| 24 { |
| 25 FetchDataLoader::trace(visitor); |
| 26 visitor->trace(m_client); |
| 27 } |
| 28 |
| 29 private: |
| 30 void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client)
override |
| 31 { |
| 32 ASSERT(!m_client); |
| 33 ASSERT(!m_reader); |
| 34 |
| 35 m_client = client; |
| 36 // Passing |this| here is safe because |this| owns |m_reader|. |
| 37 m_reader = handle->obtainReader(this); |
| 38 RefPtr<BlobDataHandle> blobHandle = m_reader->drainAsBlobDataHandle(); |
| 39 if (blobHandle) { |
| 40 ASSERT(blobHandle->size() != kuint64max); |
| 41 m_reader.clear(); |
| 42 if (blobHandle->type() != m_mimeType) { |
| 43 // A new BlobDataHandle is created to override the Blob's type. |
| 44 m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(bl
obHandle->uuid(), m_mimeType, blobHandle->size())); |
| 45 } else { |
| 46 m_client->didFetchDataLoadedBlobHandle(blobHandle); |
| 47 } |
| 48 m_client.clear(); |
| 49 return; |
| 50 } |
| 51 |
| 52 // We read data from |m_reader| and create a new blob. |
| 53 m_blobData = BlobData::create(); |
| 54 m_blobData->setContentType(m_mimeType); |
| 55 } |
| 56 |
| 57 void didGetReadable() override |
| 58 { |
| 59 ASSERT(m_client); |
| 60 ASSERT(m_reader); |
| 61 |
| 62 while (true) { |
| 63 const void* buffer; |
| 64 size_t available; |
| 65 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer,
WebDataConsumerHandle::FlagNone, &available); |
| 66 |
| 67 switch (result) { |
| 68 case WebDataConsumerHandle::Ok: |
| 69 m_blobData->appendBytes(buffer, available); |
| 70 m_reader->endRead(available); |
| 71 break; |
| 72 |
| 73 case WebDataConsumerHandle::Done: { |
| 74 m_reader.clear(); |
| 75 long long size = m_blobData->length(); |
| 76 m_client->didFetchDataLoadedBlobHandle(BlobDataHandle::create(m_
blobData.release(), size)); |
| 77 m_client.clear(); |
| 78 return; |
| 79 } |
| 80 |
| 81 case WebDataConsumerHandle::ShouldWait: |
| 82 return; |
| 83 |
| 84 case WebDataConsumerHandle::Busy: |
| 85 case WebDataConsumerHandle::ResourceExhausted: |
| 86 case WebDataConsumerHandle::UnexpectedError: { |
| 87 m_reader.clear(); |
| 88 m_blobData.clear(); |
| 89 m_client->didFetchDataLoadFailed(); |
| 90 m_client.clear(); |
| 91 return; |
| 92 } |
| 93 } |
| 94 } |
| 95 } |
| 96 |
| 97 void cancel() override |
| 98 { |
| 99 m_reader.clear(); |
| 100 m_blobData.clear(); |
| 101 m_client.clear(); |
| 102 } |
| 103 |
| 104 OwnPtr<FetchDataConsumerHandle::Reader> m_reader; |
| 105 Member<FetchDataLoader::Client> m_client; |
| 106 |
| 107 String m_mimeType; |
| 108 OwnPtr<BlobData> m_blobData; |
| 109 }; |
| 110 |
| 111 class FetchDataLoaderAsArrayBufferOrString |
| 112 : public FetchDataLoader |
| 113 , public WebDataConsumerHandle::Client { |
| 114 public: |
| 115 enum LoadType { |
| 116 LoadAsArrayBuffer, |
| 117 LoadAsString |
| 118 }; |
| 119 |
| 120 explicit FetchDataLoaderAsArrayBufferOrString(LoadType loadType) |
| 121 : m_client(nullptr) |
| 122 , m_loadType(loadType) { } |
| 123 |
| 124 DEFINE_INLINE_VIRTUAL_TRACE() |
| 125 { |
| 126 FetchDataLoader::trace(visitor); |
| 127 visitor->trace(m_client); |
| 128 } |
| 129 |
| 130 protected: |
| 131 void start(FetchDataConsumerHandle* handle, FetchDataLoader::Client* client)
override |
| 132 { |
| 133 ASSERT(!m_client); |
| 134 ASSERT(!m_rawData); |
| 135 ASSERT(!m_reader); |
| 136 m_client = client; |
| 137 m_rawData = adoptPtr(new ArrayBufferBuilder()); |
| 138 m_reader = handle->obtainReader(this); |
| 139 } |
| 140 |
| 141 void didGetReadable() override |
| 142 { |
| 143 ASSERT(m_client); |
| 144 ASSERT(m_rawData); |
| 145 ASSERT(m_reader); |
| 146 |
| 147 while (true) { |
| 148 const void* buffer; |
| 149 size_t available; |
| 150 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer,
WebDataConsumerHandle::FlagNone, &available); |
| 151 |
| 152 switch (result) { |
| 153 case WebDataConsumerHandle::Ok: |
| 154 if (available > 0) { |
| 155 unsigned bytesAppended = m_rawData->append(static_cast<const
char*>(buffer), available); |
| 156 if (!bytesAppended) { |
| 157 m_reader->endRead(0); |
| 158 error(); |
| 159 return; |
| 160 } |
| 161 ASSERT(bytesAppended == available); |
| 162 } |
| 163 m_reader->endRead(available); |
| 164 break; |
| 165 |
| 166 case WebDataConsumerHandle::Done: { |
| 167 m_reader.clear(); |
| 168 switch (m_loadType) { |
| 169 case LoadAsArrayBuffer: |
| 170 m_client->didFetchDataLoadedArrayBuffer(DOMArrayBuffer::crea
te(m_rawData->toArrayBuffer())); |
| 171 break; |
| 172 case LoadAsString: |
| 173 m_client->didFetchDataLoadedString(m_rawData->toString()); |
| 174 break; |
| 175 } |
| 176 m_rawData.clear(); |
| 177 m_client.clear(); |
| 178 return; |
| 179 } |
| 180 |
| 181 case WebDataConsumerHandle::ShouldWait: |
| 182 return; |
| 183 |
| 184 case WebDataConsumerHandle::Busy: |
| 185 case WebDataConsumerHandle::ResourceExhausted: |
| 186 case WebDataConsumerHandle::UnexpectedError: |
| 187 error(); |
| 188 return; |
| 189 } |
| 190 } |
| 191 } |
| 192 |
| 193 void error() |
| 194 { |
| 195 m_reader.clear(); |
| 196 m_rawData.clear(); |
| 197 m_client->didFetchDataLoadFailed(); |
| 198 m_client.clear(); |
| 199 } |
| 200 |
| 201 void cancel() override |
| 202 { |
| 203 m_reader.clear(); |
| 204 m_rawData.clear(); |
| 205 m_client.clear(); |
| 206 } |
| 207 |
| 208 OwnPtr<FetchDataConsumerHandle::Reader> m_reader; |
| 209 Member<FetchDataLoader::Client> m_client; |
| 210 |
| 211 LoadType m_loadType; |
| 212 OwnPtr<ArrayBufferBuilder> m_rawData; |
| 213 }; |
| 214 |
| 215 } // namespace |
| 216 |
| 217 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle(const String& mimeTyp
e) |
| 218 { |
| 219 return new FetchDataLoaderAsBlobHandle(mimeType); |
| 220 } |
| 221 |
| 222 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() |
| 223 { |
| 224 return new FetchDataLoaderAsArrayBufferOrString(FetchDataLoaderAsArrayBuffer
OrString::LoadAsArrayBuffer); |
| 225 } |
| 226 |
| 227 FetchDataLoader* FetchDataLoader::createLoaderAsString() |
| 228 { |
| 229 return new FetchDataLoaderAsArrayBufferOrString(FetchDataLoaderAsArrayBuffer
OrString::LoadAsString); |
| 230 } |
| 231 |
| 232 } // namespace blink |
| OLD | NEW |