| Index: Source/modules/fetch/BodyStreamBuffer.h
|
| diff --git a/Source/modules/fetch/BodyStreamBuffer.h b/Source/modules/fetch/BodyStreamBuffer.h
|
| index cdb47baab116261c68167786d96f4c924f8e15d1..1e1fb23e4aa462786cf16215b434455af93bc72b 100644
|
| --- a/Source/modules/fetch/BodyStreamBuffer.h
|
| +++ b/Source/modules/fetch/BodyStreamBuffer.h
|
| @@ -7,6 +7,9 @@
|
|
|
| #include "core/dom/DOMException.h"
|
| #include "modules/ModulesExport.h"
|
| +#include "modules/fetch/DataConsumerHandleUtil.h"
|
| +#include "modules/fetch/FetchDataConsumerHandle.h"
|
| +#include "modules/fetch/FetchDataLoader.h"
|
| #include "platform/blob/BlobData.h"
|
| #include "platform/heap/Heap.h"
|
| #include "public/platform/WebDataConsumerHandle.h"
|
| @@ -18,71 +21,227 @@ namespace blink {
|
|
|
| class DOMArrayBuffer;
|
|
|
| -class MODULES_EXPORT BodyStreamBuffer final : public GarbageCollectedFinalized<BodyStreamBuffer> {
|
| +/*
|
| +// #define createDebugHandleAlways(handle) FetchDebugDataConsumerHandle::create(handle, __FILE__, __LINE__)
|
| +#define createDebugHandleAlways(handle) (handle)
|
| +#define createDebugHandle(handle) (handle)
|
| +
|
| +class FetchDebugDataConsumerHandle : public FetchDataConsumerHandle {
|
| public:
|
| - class Observer : public GarbageCollectedFinalized<Observer> {
|
| + static PassOwnPtr<FetchDataConsumerHandle> create(PassOwnPtr<FetchDataConsumerHandle> handle, const char* file, int line) { return adoptPtr(new FetchDebugDataConsumerHandle(handle, file, line)); }
|
| +private:
|
| + FetchDebugDataConsumerHandle(PassOwnPtr<FetchDataConsumerHandle> handle, const char *file, int line)
|
| + : m_handle(handle)
|
| + , m_name(m_handle->debugName()) { }
|
| +
|
| + class ReaderImpl final : public FetchDataConsumerHandle::Reader {
|
| public:
|
| - virtual ~Observer() { }
|
| - virtual void onWrite() = 0;
|
| - virtual void onClose() = 0;
|
| - virtual void onError() = 0;
|
| - DEFINE_INLINE_VIRTUAL_TRACE() { }
|
| + ReaderImpl(FetchDebugDataConsumerHandle* handle, PassOwnPtr<FetchDataConsumerHandle::Reader> reader) : m_handle(handle), m_name(handle->debugName()), m_reader(reader), m_isInTwoPhaseRead(false) { }
|
| + ~ReaderImpl()
|
| + {
|
| + ASSERT(!m_isInTwoPhaseRead);
|
| + print("dtor\n", (long long)currentThread(), this);
|
| + }
|
| + Result read(void* data, size_t size, Flags flags, size_t* readSize) override
|
| + {
|
| + ASSERT(!m_isInTwoPhaseRead);
|
| + print("read(%lld)\n", (long long)size);
|
| + Result result = m_reader->read(data, size, flags, readSize);
|
| + print("read(%lld) -> %d (%lld)\n", (long long)size, result, (long long)*readSize);
|
| + return result;
|
| + }
|
| +
|
| + Result beginRead(const void** buffer, Flags flags, size_t* available) override
|
| + {
|
| + ASSERT(!m_isInTwoPhaseRead);
|
| + print("beginRead()\n");
|
| + Result result = m_reader->beginRead(buffer, flags, available);
|
| + print("beginRead() -> %d (%lld)\n", result, (long long)*available);
|
| + if (result == Ok)
|
| + m_isInTwoPhaseRead = true;
|
| + return result;
|
| + }
|
| + Result endRead(size_t readSize) override
|
| + {
|
| + ASSERT(m_isInTwoPhaseRead);
|
| + m_isInTwoPhaseRead = false;
|
| + print("endRead(%lld)\n", (long long)readSize);
|
| + Result result = m_reader->endRead(readSize);
|
| + print("endRead(%lld) -> %d\n", (long long)readSize, result);
|
| + return result;
|
| + }
|
| + PassRefPtr<BlobDataHandle> drainAsBlobDataHandle() override
|
| + {
|
| + print("drainAsBlobDataHandle()\n");
|
| + RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle();
|
| + print("drainAsBlobDataHandle() -> %p\n", blobDataHandle.get());
|
| + return blobDataHandle.release();
|
| + }
|
| + void print(const char* format, ...)
|
| + {
|
| + fprintf(stderr, "[Thread:%lld] [Handle:%p (%s)] [Reader:%p] [TargetReader:%p]: ",
|
| + (long long)currentThread(),
|
| + m_handle,
|
| + m_name.c_str(),
|
| + this,
|
| + m_reader.get());
|
| +
|
| + va_list args;
|
| + va_start(args, format);
|
| + vfprintf(stderr, format, args);
|
| + va_end(args);
|
| + }
|
| + private:
|
| + FetchDebugDataConsumerHandle* m_handle; // debugging only
|
| + std::string m_name;
|
| + OwnPtr<FetchDataConsumerHandle::Reader> m_reader;
|
| + bool m_isInTwoPhaseRead;
|
| };
|
| -
|
| - class Canceller : public GarbageCollected<Canceller> {
|
| + class ClientWrapper : public Client {
|
| public:
|
| - virtual void cancel() = 0;
|
| - DEFINE_INLINE_VIRTUAL_TRACE() { }
|
| + ClientWrapper(FetchDebugDataConsumerHandle* handle, Client* client) : m_handle(handle), m_name(handle->debugName()), m_reader(nullptr), m_client(client) { }
|
| + void didGetReadable() override
|
| + {
|
| + print("didGetReadable\n");
|
| + if (m_client)
|
| + m_client->didGetReadable();
|
| + print("didGetReadable done\n");
|
| + }
|
| + void setReader(Reader* reader) { m_reader = reader; }
|
| +
|
| + void print(const char* format, ...)
|
| + {
|
| + fprintf(stderr, "[Thread:%lld] [Handle:%p (%s)] [Reader:%p] [Client:%p] [TargetClient:%p]: ",
|
| + (long long)currentThread(),
|
| + m_handle,
|
| + m_name.c_str(),
|
| + m_reader,
|
| + this,
|
| + m_client);
|
| +
|
| + va_list args;
|
| + va_start(args, format);
|
| + vfprintf(stderr, format, args);
|
| + va_end(args);
|
| + }
|
| + private:
|
| + FetchDebugDataConsumerHandle* m_handle; // debugging only
|
| + std::string m_name;
|
| + Reader* m_reader; // logging only
|
| +
|
| + Client* m_client;
|
| };
|
| + Reader* obtainReaderInternal(Client* client) override
|
| + {
|
| + print("obtainReaderInternal(Client=%p)\n", client);
|
| + ClientWrapper* clientWrapper = new ClientWrapper(this, client);
|
| + Reader* reader = new ReaderImpl(this, m_handle->obtainReader(clientWrapper)); // FIXME: Leaking
|
| + clientWrapper->setReader(reader);
|
| + print("obtainReaderInternal(Client=%p) -> %p\n", client, reader);
|
| + return reader;
|
| + }
|
| + void print(const char* format, ...)
|
| + {
|
| + fprintf(stderr, "[Thread:%lld] [Handle:%p (%s)]: ",
|
| + (long long)currentThread(),
|
| + this,
|
| + debugName());
|
| +
|
| + va_list args;
|
| + va_start(args, format);
|
| + vfprintf(stderr, format, args);
|
| + va_end(args);
|
| + }
|
| +
|
| + const char* debugName() const override { return m_name.c_str(); }
|
| +
|
| + OwnPtr<FetchDataConsumerHandle> m_handle;
|
| + std::string m_name;
|
| +};
|
| +*/
|
|
|
| - class BlobHandleCreatorClient : public GarbageCollectedFinalized<BlobHandleCreatorClient> {
|
| +class MODULES_EXPORT BodyStreamBuffer final : public GarbageCollectedFinalized<BodyStreamBuffer> {
|
| +public:
|
| + static BodyStreamBuffer* create(PassOwnPtr<FetchDataConsumerHandle> handle) { return new BodyStreamBuffer(handle); }
|
| + static BodyStreamBuffer* createEmpty() { return BodyStreamBuffer::create(createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle())); }
|
| +
|
| + FetchDataConsumerHandle* handle() const { return m_handle.get(); }
|
| + PassOwnPtr<FetchDataConsumerHandle> releaseHandle() { return m_handle.release(); }
|
| +
|
| + void startLoading(FetchDataLoader* fetchDataLoader, FetchDataLoader::Client* client)
|
| + {
|
| + ASSERT(!m_fetchDataLoader);
|
| + m_fetchDataLoader = fetchDataLoader;
|
| + m_fetchDataLoader->start(handle(), new ClientWithFinishNotification(this, client));
|
| + }
|
| +
|
| + void didFetchDataLoadFinished()
|
| + {
|
| + ASSERT(m_fetchDataLoader);
|
| + m_fetchDataLoader.clear();
|
| + }
|
| +
|
| + DEFINE_INLINE_TRACE()
|
| + {
|
| + visitor->trace(m_fetchDataLoader);
|
| + }
|
| +
|
| +private:
|
| + explicit BodyStreamBuffer(PassOwnPtr<FetchDataConsumerHandle> handle) : m_handle(handle) { }
|
| +
|
| + class ClientWithFinishNotification final : public GarbageCollectedFinalized<ClientWithFinishNotification>, public FetchDataLoader::Client {
|
| + USING_GARBAGE_COLLECTED_MIXIN(ClientWithFinishNotification);
|
| public:
|
| - virtual ~BlobHandleCreatorClient() { }
|
| - virtual void didCreateBlobHandle(PassRefPtr<BlobDataHandle>) = 0;
|
| - virtual void didFail(DOMException*) = 0;
|
| - DEFINE_INLINE_VIRTUAL_TRACE() { }
|
| + ClientWithFinishNotification(BodyStreamBuffer* buffer, FetchDataLoader::Client* client)
|
| + : m_buffer(buffer)
|
| + , m_client(client)
|
| + {
|
| + }
|
| +
|
| + DEFINE_INLINE_VIRTUAL_TRACE()
|
| + {
|
| + visitor->trace(m_buffer);
|
| + visitor->trace(m_client);
|
| + FetchDataLoader::Client::trace(visitor);
|
| + }
|
| + private:
|
| + void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) override
|
| + {
|
| + m_buffer->didFetchDataLoadFinished();
|
| + if (m_client)
|
| + m_client->didFetchDataLoadedBlobHandle(blobDataHandle);
|
| + }
|
| + void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) override
|
| + {
|
| + m_buffer->didFetchDataLoadFinished();
|
| + if (m_client)
|
| + m_client->didFetchDataLoadedArrayBuffer(arrayBuffer);
|
| + }
|
| + void didFetchDataLoadedString(const String& str) override
|
| + {
|
| + m_buffer->didFetchDataLoadFinished();
|
| + if (m_client)
|
| + m_client->didFetchDataLoadedString(str);
|
| + }
|
| + void didFetchDataLoadedStream() override
|
| + {
|
| + m_buffer->didFetchDataLoadFinished();
|
| + if (m_client)
|
| + m_client->didFetchDataLoadedStream();
|
| + }
|
| + void didFetchDataLoadFailed() override
|
| + {
|
| + m_buffer->didFetchDataLoadFinished();
|
| + if (m_client)
|
| + m_client->didFetchDataLoadFailed();
|
| + }
|
| +
|
| + Member<BodyStreamBuffer> m_buffer;
|
| + Member<FetchDataLoader::Client> m_client;
|
| };
|
| - explicit BodyStreamBuffer(Canceller*);
|
| - ~BodyStreamBuffer() { }
|
| -
|
| - PassRefPtr<DOMArrayBuffer> read();
|
| - bool isClosed() const { return m_isClosed; }
|
| - bool hasError() const { return m_exception; }
|
| - DOMException* exception() const { return m_exception; }
|
| -
|
| - // Can't call after close() or error() was called.
|
| - void write(PassRefPtr<DOMArrayBuffer>);
|
| - // Can't call after close() or error() was called.
|
| - void close();
|
| - // Can't call after close() or error() was called.
|
| - void error(DOMException*);
|
| - void cancel() { m_canceller->cancel(); }
|
| -
|
| - // This function registers an observer so it fails and returns false when an
|
| - // observer was already registered.
|
| - bool readAllAndCreateBlobHandle(const String& contentType, BlobHandleCreatorClient*);
|
| -
|
| - // This function registers an observer so it fails and returns false when an
|
| - // observer was already registered.
|
| - bool startTee(BodyStreamBuffer* out1, BodyStreamBuffer* out2);
|
| -
|
| - // When an observer was registered this function fails and returns false.
|
| - bool registerObserver(Observer*);
|
| - void unregisterObserver();
|
| - bool isObserverRegistered() const { return m_observer.get(); }
|
| - DECLARE_TRACE();
|
| -
|
| - // Creates a BodyStreamBuffer from |handle| as the source.
|
| - // On failure, BodyStreamBuffer::error() is called with a NetworkError
|
| - // with |failureMessage|.
|
| - static BodyStreamBuffer* create(PassOwnPtr<WebDataConsumerHandle> /* handle */, const String& failureMessage);
|
|
|
| -private:
|
| - Deque<RefPtr<DOMArrayBuffer>> m_queue;
|
| - bool m_isClosed;
|
| - Member<DOMException> m_exception;
|
| - Member<Observer> m_observer;
|
| - Member<Canceller> m_canceller;
|
| + OwnPtr<FetchDataConsumerHandle> m_handle;
|
| + Member<FetchDataLoader> m_fetchDataLoader;
|
| };
|
|
|
| } // namespace blink
|
|
|