summaryrefslogtreecommitdiff
path: root/Source/WebCore/fileapi/FileReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/fileapi/FileReader.cpp')
-rw-r--r--Source/WebCore/fileapi/FileReader.cpp152
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)