OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 #ifndef BodyStreamBuffer_h | 5 #ifndef BodyStreamBuffer_h |
6 #define BodyStreamBuffer_h | 6 #define BodyStreamBuffer_h |
7 | 7 |
8 #include "core/dom/DOMException.h" | 8 #include "core/dom/DOMException.h" |
9 #include "modules/ModulesExport.h" | 9 #include "modules/ModulesExport.h" |
| 10 #include "modules/fetch/DataConsumerHandleUtil.h" |
| 11 #include "modules/fetch/FetchDataConsumerHandle.h" |
| 12 #include "modules/fetch/FetchDataLoader.h" |
10 #include "platform/blob/BlobData.h" | 13 #include "platform/blob/BlobData.h" |
11 #include "platform/heap/Heap.h" | 14 #include "platform/heap/Heap.h" |
12 #include "public/platform/WebDataConsumerHandle.h" | 15 #include "public/platform/WebDataConsumerHandle.h" |
13 #include "wtf/Deque.h" | 16 #include "wtf/Deque.h" |
14 #include "wtf/RefPtr.h" | 17 #include "wtf/RefPtr.h" |
15 #include "wtf/text/WTFString.h" | 18 #include "wtf/text/WTFString.h" |
16 | 19 |
17 namespace blink { | 20 namespace blink { |
18 | 21 |
19 class DOMArrayBuffer; | 22 class DOMArrayBuffer; |
20 | 23 |
| 24 /* |
| 25 // #define createDebugHandleAlways(handle) FetchDebugDataConsumerHandle::create(
handle, __FILE__, __LINE__) |
| 26 #define createDebugHandleAlways(handle) (handle) |
| 27 #define createDebugHandle(handle) (handle) |
| 28 |
| 29 class FetchDebugDataConsumerHandle : public FetchDataConsumerHandle { |
| 30 public: |
| 31 static PassOwnPtr<FetchDataConsumerHandle> create(PassOwnPtr<FetchDataConsum
erHandle> handle, const char* file, int line) { return adoptPtr(new FetchDebugDa
taConsumerHandle(handle, file, line)); } |
| 32 private: |
| 33 FetchDebugDataConsumerHandle(PassOwnPtr<FetchDataConsumerHandle> handle, con
st char *file, int line) |
| 34 : m_handle(handle) |
| 35 , m_name(m_handle->debugName()) { } |
| 36 |
| 37 class ReaderImpl final : public FetchDataConsumerHandle::Reader { |
| 38 public: |
| 39 ReaderImpl(FetchDebugDataConsumerHandle* handle, PassOwnPtr<FetchDataCon
sumerHandle::Reader> reader) : m_handle(handle), m_name(handle->debugName()), m_
reader(reader), m_isInTwoPhaseRead(false) { } |
| 40 ~ReaderImpl() |
| 41 { |
| 42 ASSERT(!m_isInTwoPhaseRead); |
| 43 print("dtor\n", (long long)currentThread(), this); |
| 44 } |
| 45 Result read(void* data, size_t size, Flags flags, size_t* readSize) over
ride |
| 46 { |
| 47 ASSERT(!m_isInTwoPhaseRead); |
| 48 print("read(%lld)\n", (long long)size); |
| 49 Result result = m_reader->read(data, size, flags, readSize); |
| 50 print("read(%lld) -> %d (%lld)\n", (long long)size, result, (long lo
ng)*readSize); |
| 51 return result; |
| 52 } |
| 53 |
| 54 Result beginRead(const void** buffer, Flags flags, size_t* available) ov
erride |
| 55 { |
| 56 ASSERT(!m_isInTwoPhaseRead); |
| 57 print("beginRead()\n"); |
| 58 Result result = m_reader->beginRead(buffer, flags, available); |
| 59 print("beginRead() -> %d (%lld)\n", result, (long long)*available); |
| 60 if (result == Ok) |
| 61 m_isInTwoPhaseRead = true; |
| 62 return result; |
| 63 } |
| 64 Result endRead(size_t readSize) override |
| 65 { |
| 66 ASSERT(m_isInTwoPhaseRead); |
| 67 m_isInTwoPhaseRead = false; |
| 68 print("endRead(%lld)\n", (long long)readSize); |
| 69 Result result = m_reader->endRead(readSize); |
| 70 print("endRead(%lld) -> %d\n", (long long)readSize, result); |
| 71 return result; |
| 72 } |
| 73 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle() override |
| 74 { |
| 75 print("drainAsBlobDataHandle()\n"); |
| 76 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHan
dle(); |
| 77 print("drainAsBlobDataHandle() -> %p\n", blobDataHandle.get()); |
| 78 return blobDataHandle.release(); |
| 79 } |
| 80 void print(const char* format, ...) |
| 81 { |
| 82 fprintf(stderr, "[Thread:%lld] [Handle:%p (%s)] [Reader:%p] [TargetR
eader:%p]: ", |
| 83 (long long)currentThread(), |
| 84 m_handle, |
| 85 m_name.c_str(), |
| 86 this, |
| 87 m_reader.get()); |
| 88 |
| 89 va_list args; |
| 90 va_start(args, format); |
| 91 vfprintf(stderr, format, args); |
| 92 va_end(args); |
| 93 } |
| 94 private: |
| 95 FetchDebugDataConsumerHandle* m_handle; // debugging only |
| 96 std::string m_name; |
| 97 OwnPtr<FetchDataConsumerHandle::Reader> m_reader; |
| 98 bool m_isInTwoPhaseRead; |
| 99 }; |
| 100 class ClientWrapper : public Client { |
| 101 public: |
| 102 ClientWrapper(FetchDebugDataConsumerHandle* handle, Client* client) : m_
handle(handle), m_name(handle->debugName()), m_reader(nullptr), m_client(client)
{ } |
| 103 void didGetReadable() override |
| 104 { |
| 105 print("didGetReadable\n"); |
| 106 if (m_client) |
| 107 m_client->didGetReadable(); |
| 108 print("didGetReadable done\n"); |
| 109 } |
| 110 void setReader(Reader* reader) { m_reader = reader; } |
| 111 |
| 112 void print(const char* format, ...) |
| 113 { |
| 114 fprintf(stderr, "[Thread:%lld] [Handle:%p (%s)] [Reader:%p] [Client:
%p] [TargetClient:%p]: ", |
| 115 (long long)currentThread(), |
| 116 m_handle, |
| 117 m_name.c_str(), |
| 118 m_reader, |
| 119 this, |
| 120 m_client); |
| 121 |
| 122 va_list args; |
| 123 va_start(args, format); |
| 124 vfprintf(stderr, format, args); |
| 125 va_end(args); |
| 126 } |
| 127 private: |
| 128 FetchDebugDataConsumerHandle* m_handle; // debugging only |
| 129 std::string m_name; |
| 130 Reader* m_reader; // logging only |
| 131 |
| 132 Client* m_client; |
| 133 }; |
| 134 Reader* obtainReaderInternal(Client* client) override |
| 135 { |
| 136 print("obtainReaderInternal(Client=%p)\n", client); |
| 137 ClientWrapper* clientWrapper = new ClientWrapper(this, client); |
| 138 Reader* reader = new ReaderImpl(this, m_handle->obtainReader(clientWrapp
er)); // FIXME: Leaking |
| 139 clientWrapper->setReader(reader); |
| 140 print("obtainReaderInternal(Client=%p) -> %p\n", client, reader); |
| 141 return reader; |
| 142 } |
| 143 void print(const char* format, ...) |
| 144 { |
| 145 fprintf(stderr, "[Thread:%lld] [Handle:%p (%s)]: ", |
| 146 (long long)currentThread(), |
| 147 this, |
| 148 debugName()); |
| 149 |
| 150 va_list args; |
| 151 va_start(args, format); |
| 152 vfprintf(stderr, format, args); |
| 153 va_end(args); |
| 154 } |
| 155 |
| 156 const char* debugName() const override { return m_name.c_str(); } |
| 157 |
| 158 OwnPtr<FetchDataConsumerHandle> m_handle; |
| 159 std::string m_name; |
| 160 }; |
| 161 */ |
| 162 |
21 class MODULES_EXPORT BodyStreamBuffer final : public GarbageCollectedFinalized<B
odyStreamBuffer> { | 163 class MODULES_EXPORT BodyStreamBuffer final : public GarbageCollectedFinalized<B
odyStreamBuffer> { |
22 public: | 164 public: |
23 class Observer : public GarbageCollectedFinalized<Observer> { | 165 static BodyStreamBuffer* create(PassOwnPtr<FetchDataConsumerHandle> handle)
{ return new BodyStreamBuffer(handle); } |
| 166 static BodyStreamBuffer* createEmpty() { return BodyStreamBuffer::create(cre
ateFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle())); } |
| 167 |
| 168 FetchDataConsumerHandle* handle() const { return m_handle.get(); } |
| 169 PassOwnPtr<FetchDataConsumerHandle> releaseHandle() { return m_handle.releas
e(); } |
| 170 |
| 171 void startLoading(FetchDataLoader* fetchDataLoader, FetchDataLoader::Client*
client) |
| 172 { |
| 173 ASSERT(!m_fetchDataLoader); |
| 174 m_fetchDataLoader = fetchDataLoader; |
| 175 m_fetchDataLoader->start(handle(), new ClientWithFinishNotification(this
, client)); |
| 176 } |
| 177 |
| 178 void didFetchDataLoadFinished() |
| 179 { |
| 180 ASSERT(m_fetchDataLoader); |
| 181 m_fetchDataLoader.clear(); |
| 182 } |
| 183 |
| 184 DEFINE_INLINE_TRACE() |
| 185 { |
| 186 visitor->trace(m_fetchDataLoader); |
| 187 } |
| 188 |
| 189 private: |
| 190 explicit BodyStreamBuffer(PassOwnPtr<FetchDataConsumerHandle> handle) : m_ha
ndle(handle) { } |
| 191 |
| 192 class ClientWithFinishNotification final : public GarbageCollectedFinalized<
ClientWithFinishNotification>, public FetchDataLoader::Client { |
| 193 USING_GARBAGE_COLLECTED_MIXIN(ClientWithFinishNotification); |
24 public: | 194 public: |
25 virtual ~Observer() { } | 195 ClientWithFinishNotification(BodyStreamBuffer* buffer, FetchDataLoader::
Client* client) |
26 virtual void onWrite() = 0; | 196 : m_buffer(buffer) |
27 virtual void onClose() = 0; | 197 , m_client(client) |
28 virtual void onError() = 0; | 198 { |
29 DEFINE_INLINE_VIRTUAL_TRACE() { } | 199 } |
| 200 |
| 201 DEFINE_INLINE_VIRTUAL_TRACE() |
| 202 { |
| 203 visitor->trace(m_buffer); |
| 204 visitor->trace(m_client); |
| 205 FetchDataLoader::Client::trace(visitor); |
| 206 } |
| 207 private: |
| 208 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHan
dle) override |
| 209 { |
| 210 m_buffer->didFetchDataLoadFinished(); |
| 211 if (m_client) |
| 212 m_client->didFetchDataLoadedBlobHandle(blobDataHandle); |
| 213 } |
| 214 void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffe
r) override |
| 215 { |
| 216 m_buffer->didFetchDataLoadFinished(); |
| 217 if (m_client) |
| 218 m_client->didFetchDataLoadedArrayBuffer(arrayBuffer); |
| 219 } |
| 220 void didFetchDataLoadedString(const String& str) override |
| 221 { |
| 222 m_buffer->didFetchDataLoadFinished(); |
| 223 if (m_client) |
| 224 m_client->didFetchDataLoadedString(str); |
| 225 } |
| 226 void didFetchDataLoadedStream() override |
| 227 { |
| 228 m_buffer->didFetchDataLoadFinished(); |
| 229 if (m_client) |
| 230 m_client->didFetchDataLoadedStream(); |
| 231 } |
| 232 void didFetchDataLoadFailed() override |
| 233 { |
| 234 m_buffer->didFetchDataLoadFinished(); |
| 235 if (m_client) |
| 236 m_client->didFetchDataLoadFailed(); |
| 237 } |
| 238 |
| 239 Member<BodyStreamBuffer> m_buffer; |
| 240 Member<FetchDataLoader::Client> m_client; |
30 }; | 241 }; |
31 | 242 |
32 class Canceller : public GarbageCollected<Canceller> { | 243 OwnPtr<FetchDataConsumerHandle> m_handle; |
33 public: | 244 Member<FetchDataLoader> m_fetchDataLoader; |
34 virtual void cancel() = 0; | |
35 DEFINE_INLINE_VIRTUAL_TRACE() { } | |
36 }; | |
37 | |
38 class BlobHandleCreatorClient : public GarbageCollectedFinalized<BlobHandleC
reatorClient> { | |
39 public: | |
40 virtual ~BlobHandleCreatorClient() { } | |
41 virtual void didCreateBlobHandle(PassRefPtr<BlobDataHandle>) = 0; | |
42 virtual void didFail(DOMException*) = 0; | |
43 DEFINE_INLINE_VIRTUAL_TRACE() { } | |
44 }; | |
45 explicit BodyStreamBuffer(Canceller*); | |
46 ~BodyStreamBuffer() { } | |
47 | |
48 PassRefPtr<DOMArrayBuffer> read(); | |
49 bool isClosed() const { return m_isClosed; } | |
50 bool hasError() const { return m_exception; } | |
51 DOMException* exception() const { return m_exception; } | |
52 | |
53 // Can't call after close() or error() was called. | |
54 void write(PassRefPtr<DOMArrayBuffer>); | |
55 // Can't call after close() or error() was called. | |
56 void close(); | |
57 // Can't call after close() or error() was called. | |
58 void error(DOMException*); | |
59 void cancel() { m_canceller->cancel(); } | |
60 | |
61 // This function registers an observer so it fails and returns false when an | |
62 // observer was already registered. | |
63 bool readAllAndCreateBlobHandle(const String& contentType, BlobHandleCreator
Client*); | |
64 | |
65 // This function registers an observer so it fails and returns false when an | |
66 // observer was already registered. | |
67 bool startTee(BodyStreamBuffer* out1, BodyStreamBuffer* out2); | |
68 | |
69 // When an observer was registered this function fails and returns false. | |
70 bool registerObserver(Observer*); | |
71 void unregisterObserver(); | |
72 bool isObserverRegistered() const { return m_observer.get(); } | |
73 DECLARE_TRACE(); | |
74 | |
75 // Creates a BodyStreamBuffer from |handle| as the source. | |
76 // On failure, BodyStreamBuffer::error() is called with a NetworkError | |
77 // with |failureMessage|. | |
78 static BodyStreamBuffer* create(PassOwnPtr<WebDataConsumerHandle> /* handle
*/, const String& failureMessage); | |
79 | |
80 private: | |
81 Deque<RefPtr<DOMArrayBuffer>> m_queue; | |
82 bool m_isClosed; | |
83 Member<DOMException> m_exception; | |
84 Member<Observer> m_observer; | |
85 Member<Canceller> m_canceller; | |
86 }; | 245 }; |
87 | 246 |
88 } // namespace blink | 247 } // namespace blink |
89 | 248 |
90 #endif // BodyStreamBuffer_h | 249 #endif // BodyStreamBuffer_h |
OLD | NEW |