diff options
Diffstat (limited to 'Source/WebCore/fileapi/FileReader.cpp')
-rw-r--r-- | Source/WebCore/fileapi/FileReader.cpp | 152 |
1 files changed, 66 insertions, 86 deletions
diff --git a/Source/WebCore/fileapi/FileReader.cpp b/Source/WebCore/fileapi/FileReader.cpp index 0025bc045..ea46dd9d6 100644 --- a/Source/WebCore/fileapi/FileReader.cpp +++ b/Source/WebCore/fileapi/FileReader.cpp @@ -29,12 +29,9 @@ */ #include "config.h" - -#if ENABLE(BLOB) - #include "FileReader.h" -#include "CrossThreadTask.h" +#include "EventNames.h" #include "ExceptionCode.h" #include "File.h" #include "Logging.h" @@ -46,109 +43,107 @@ namespace WebCore { -static const auto progressNotificationInterval = std::chrono::milliseconds(50); +// Fire the progress event at least every 50ms. +static const auto progressNotificationInterval = 50ms; -PassRefPtr<FileReader> FileReader::create(ScriptExecutionContext& context) +Ref<FileReader> FileReader::create(ScriptExecutionContext& context) { - RefPtr<FileReader> fileReader(adoptRef(new FileReader(context))); + auto fileReader = adoptRef(*new FileReader(context)); fileReader->suspendIfNeeded(); - return fileReader.release(); + return fileReader; } FileReader::FileReader(ScriptExecutionContext& context) : ActiveDOMObject(&context) - , m_state(EMPTY) - , m_aborting(false) - , m_readType(FileReaderLoader::ReadAsBinaryString) { } FileReader::~FileReader() { - terminate(); + if (m_loader) + m_loader->cancel(); } -bool FileReader::canSuspend() const +bool FileReader::canSuspendForDocumentSuspension() const { // FIXME: It is not currently possible to suspend a FileReader, so pages with FileReader can not go into page cache. return false; } +const char* FileReader::activeDOMObjectName() const +{ + return "FileReader"; +} + void FileReader::stop() { - terminate(); + if (m_loader) { + m_loader->cancel(); + m_loader = nullptr; + } + m_state = DONE; } -void FileReader::readAsArrayBuffer(Blob* blob, ExceptionCode& ec) +ExceptionOr<void> FileReader::readAsArrayBuffer(Blob* blob) { if (!blob) - return; + return { }; - LOG(FileAPI, "FileReader: reading as array buffer: %s %s\n", blob->url().string().utf8().data(), blob->isFile() ? toFile(blob)->path().utf8().data() : ""); + LOG(FileAPI, "FileReader: reading as array buffer: %s %s\n", blob->url().string().utf8().data(), is<File>(*blob) ? downcast<File>(*blob).path().utf8().data() : ""); - readInternal(blob, FileReaderLoader::ReadAsArrayBuffer, ec); + return readInternal(*blob, FileReaderLoader::ReadAsArrayBuffer); } -void FileReader::readAsBinaryString(Blob* blob, ExceptionCode& ec) +ExceptionOr<void> FileReader::readAsBinaryString(Blob* blob) { if (!blob) - return; + return { }; - LOG(FileAPI, "FileReader: reading as binary: %s %s\n", blob->url().string().utf8().data(), blob->isFile() ? toFile(blob)->path().utf8().data() : ""); + LOG(FileAPI, "FileReader: reading as binary: %s %s\n", blob->url().string().utf8().data(), is<File>(*blob) ? downcast<File>(*blob).path().utf8().data() : ""); - readInternal(blob, FileReaderLoader::ReadAsBinaryString, ec); + return readInternal(*blob, FileReaderLoader::ReadAsBinaryString); } -void FileReader::readAsText(Blob* blob, const String& encoding, ExceptionCode& ec) +ExceptionOr<void> FileReader::readAsText(Blob* blob, const String& encoding) { if (!blob) - return; + return { }; - LOG(FileAPI, "FileReader: reading as text: %s %s\n", blob->url().string().utf8().data(), blob->isFile() ? toFile(blob)->path().utf8().data() : ""); + LOG(FileAPI, "FileReader: reading as text: %s %s\n", blob->url().string().utf8().data(), is<File>(*blob) ? downcast<File>(*blob).path().utf8().data() : ""); m_encoding = encoding; - readInternal(blob, FileReaderLoader::ReadAsText, ec); -} - -void FileReader::readAsText(Blob* blob, ExceptionCode& ec) -{ - readAsText(blob, String(), ec); + return readInternal(*blob, FileReaderLoader::ReadAsText); } -void FileReader::readAsDataURL(Blob* blob, ExceptionCode& ec) +ExceptionOr<void> FileReader::readAsDataURL(Blob* blob) { if (!blob) - return; + return { }; - LOG(FileAPI, "FileReader: reading as data URL: %s %s\n", blob->url().string().utf8().data(), blob->isFile() ? toFile(blob)->path().utf8().data() : ""); + LOG(FileAPI, "FileReader: reading as data URL: %s %s\n", blob->url().string().utf8().data(), is<File>(*blob) ? downcast<File>(*blob).path().utf8().data() : ""); - readInternal(blob, FileReaderLoader::ReadAsDataURL, ec); + return readInternal(*blob, FileReaderLoader::ReadAsDataURL); } -void FileReader::readInternal(Blob* blob, FileReaderLoader::ReadType type, ExceptionCode& ec) +ExceptionOr<void> FileReader::readInternal(Blob& blob, FileReaderLoader::ReadType type) { // If multiple concurrent read methods are called on the same FileReader, INVALID_STATE_ERR should be thrown when the state is LOADING. - if (m_state == LOADING) { - ec = INVALID_STATE_ERR; - return; - } + if (m_state == LOADING) + return Exception { INVALID_STATE_ERR }; setPendingActivity(this); - m_blob = blob; + m_blob = &blob; m_readType = type; m_state = LOADING; - m_error = 0; + m_error = nullptr; - m_loader = std::make_unique<FileReaderLoader>(m_readType, this); + m_loader = std::make_unique<FileReaderLoader>(m_readType, static_cast<FileReaderLoaderClient*>(this)); m_loader->setEncoding(m_encoding); m_loader->setDataType(m_blob->type()); - m_loader->start(scriptExecutionContext(), m_blob.get()); -} + m_loader->start(scriptExecutionContext(), blob); -static void delayedAbort(ScriptExecutionContext*, FileReader* reader) -{ - reader->doAbort(); + return { }; } void FileReader::abort() @@ -160,34 +155,21 @@ void FileReader::abort() m_aborting = true; // Schedule to have the abort done later since abort() might be called from the event handler and we do not want the resource loading code to be in the stack. - scriptExecutionContext()->postTask( - createCallbackTask(&delayedAbort, AllowAccessLater(this))); -} - -void FileReader::doAbort() -{ - ASSERT(m_state != DONE); + scriptExecutionContext()->postTask([this] (ScriptExecutionContext&) { + ASSERT(m_state != DONE); - terminate(); - m_aborting = false; + stop(); + m_aborting = false; - m_error = FileError::create(FileError::ABORT_ERR); + m_error = FileError::create(FileError::ABORT_ERR); - fireEvent(eventNames().errorEvent); - fireEvent(eventNames().abortEvent); - fireEvent(eventNames().loadendEvent); + fireEvent(eventNames().errorEvent); + fireEvent(eventNames().abortEvent); + fireEvent(eventNames().loadendEvent); - // All possible events have fired and we're done, no more pending activity. - unsetPendingActivity(this); -} - -void FileReader::terminate() -{ - if (m_loader) { - m_loader->cancel(); - m_loader = nullptr; - } - m_state = DONE; + // All possible events have fired and we're done, no more pending activity. + unsetPendingActivity(this); + }); } void FileReader::didStartLoading() @@ -197,13 +179,11 @@ void FileReader::didStartLoading() void FileReader::didReceiveData() { - // Fire the progress event at least every 50ms. auto now = std::chrono::steady_clock::now(); if (!m_lastProgressNotificationTime.time_since_epoch().count()) { m_lastProgressNotificationTime = now; return; } - if (now - m_lastProgressNotificationTime > progressNotificationInterval) { fireEvent(eventNames().progressEvent); m_lastProgressNotificationTime = now; @@ -248,20 +228,20 @@ void FileReader::fireEvent(const AtomicString& type) dispatchEvent(ProgressEvent::create(type, true, m_loader ? m_loader->bytesLoaded() : 0, m_loader ? m_loader->totalBytes() : 0)); } -PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const +std::optional<Variant<String, RefPtr<JSC::ArrayBuffer>>> FileReader::result() const { if (!m_loader || m_error) - return 0; - return m_loader->arrayBufferResult(); -} - -String FileReader::stringResult() -{ - if (!m_loader || m_error) - return String(); - return m_loader->stringResult(); + return std::nullopt; + if (m_readType == FileReaderLoader::ReadAsArrayBuffer) { + auto result = m_loader->arrayBufferResult(); + if (!result) + return std::nullopt; + return { result }; + } + String result = m_loader->stringResult(); + if (result.isNull()) + return std::nullopt; + return { WTFMove(result) }; } } // namespace WebCore - -#endif // ENABLE(BLOB) |