summaryrefslogtreecommitdiffstats
path: root/src/corelib/platform/wasm/qstdweb_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/platform/wasm/qstdweb_p.h')
-rw-r--r--src/corelib/platform/wasm/qstdweb_p.h274
1 files changed, 219 insertions, 55 deletions
diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h
index 75c2ec34b1..a3b5bd5b6b 100644
--- a/src/corelib/platform/wasm/qstdweb_p.h
+++ b/src/corelib/platform/wasm/qstdweb_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSTDWEB_P_H
#define QSTDWEB_P_H
@@ -51,17 +15,36 @@
// We mean it.
//
-#include <qglobal.h>
+#include <private/qglobal_p.h>
+#include <QtCore/qglobal.h>
+#include "QtCore/qhash.h"
+#include "QtCore/qiodevice.h"
+
#include <emscripten/val.h>
+
#include <cstdint>
#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <utility>
+
+#if QT_CONFIG(thread)
+#include <emscripten/proxying.h>
+#include <emscripten/threading.h>
+#endif // #if QT_CONFIG(thread)
QT_BEGIN_NAMESPACE
+class QMimeData;
+
namespace qstdweb {
+ extern const char makeContextfulPromiseFunctionName[];
// DOM API in C++, implemented using emscripten val.h and bind.h.
- // This is private API and can be extened and changed as needed.
+ // This is private API and can be extended and changed as needed.
+ // The API mirrors that of the native API, with some extensions
+ // to ease usage from C++ code.
class ArrayBuffer;
class Blob;
@@ -71,40 +54,84 @@ namespace qstdweb {
class Uint8Array;
class EventCallback;
- class ArrayBuffer {
+ class Q_CORE_EXPORT ArrayBuffer {
public:
+ explicit ArrayBuffer(uint32_t size);
explicit ArrayBuffer(const emscripten::val &arrayBuffer);
uint32_t byteLength() const;
+ ArrayBuffer slice(uint32_t begin, uint32_t end) const;
+ emscripten::val val() const;
private:
friend class Uint8Array;
emscripten::val m_arrayBuffer = emscripten::val::undefined();
};
- class Blob {
+ class Q_CORE_EXPORT Blob {
public:
explicit Blob(const emscripten::val &blob);
+ static Blob fromArrayBuffer(const ArrayBuffer &arrayBuffer);
uint32_t size() const;
+ static Blob copyFrom(const char *buffer, uint32_t size, std::string mimeType);
+ static Blob copyFrom(const char *buffer, uint32_t size);
+ Blob slice(uint32_t begin, uint32_t end) const;
+ ArrayBuffer arrayBuffer_sync() const;
+ emscripten::val val() const;
+ std::string type() const;
private:
friend class FileReader;
emscripten::val m_blob = emscripten::val::undefined();
};
- class File {
+ class Q_CORE_EXPORT File {
public:
File() = default;
explicit File(const emscripten::val &file);
+ ~File();
+
+ File(const File &other);
+ File(File &&other);
+ File &operator=(const File &other);
+ File &operator=(File &&other);
Blob slice(uint64_t begin, uint64_t end) const;
std::string name() const;
uint64_t size() const;
+ std::string type() const;
+ void stream(uint32_t offset, uint32_t length, char *buffer,
+ std::function<void()> completed) const;
+ void stream(char *buffer, std::function<void()> completed) const;
+ emscripten::val val() const;
+ void fileUrlRegistration() const;
+ const QString &fileUrlPath() const { return m_urlPath; }
+ emscripten::val file() const { return m_file; }
private:
emscripten::val m_file = emscripten::val::undefined();
+ QString m_urlPath;
};
- class FileList {
+ class Q_CORE_EXPORT FileUrlRegistration
+ {
+ public:
+ explicit FileUrlRegistration(File file);
+ ~FileUrlRegistration();
+
+ FileUrlRegistration(const FileUrlRegistration &other) = delete;
+ FileUrlRegistration(FileUrlRegistration &&other);
+ FileUrlRegistration &operator=(const FileUrlRegistration &other) = delete;
+ FileUrlRegistration &operator=(FileUrlRegistration &&other);
+
+ const QString &path() const { return m_path; }
+
+ private:
+ QString m_path;
+ };
+
+ using FileUrlRegistrations = std::vector<std::unique_ptr<FileUrlRegistration>>;
+
+ class Q_CORE_EXPORT FileList {
public:
FileList() = default;
explicit FileList(const emscripten::val &fileList);
@@ -112,19 +139,21 @@ namespace qstdweb {
int length() const;
File item(int index) const;
File operator[](int index) const;
+ emscripten::val val() const;
private:
emscripten::val m_fileList = emscripten::val::undefined();
};
- class FileReader {
+ class Q_CORE_EXPORT FileReader {
public:
ArrayBuffer result() const;
void readAsArrayBuffer(const Blob &blob) const;
- void onLoad(const std::function<void ()> &onLoad);
- void onError(const std::function<void ()> &onError);
- void onAbort(const std::function<void ()> &onAbort);
+ void onLoad(const std::function<void(emscripten::val)> &onLoad);
+ void onError(const std::function<void(emscripten::val)> &onError);
+ void onAbort(const std::function<void(emscripten::val)> &onAbort);
+ emscripten::val val() const;
private:
emscripten::val m_fileReader = emscripten::val::global("FileReader").new_();
@@ -133,35 +162,170 @@ namespace qstdweb {
std::unique_ptr<EventCallback> m_onAbort;
};
- class Uint8Array {
+ class Q_CORE_EXPORT Uint8Array {
public:
static Uint8Array heap();
explicit Uint8Array(const emscripten::val &uint8Array);
explicit Uint8Array(const ArrayBuffer &buffer);
+ explicit Uint8Array(uint32_t size);
Uint8Array(const ArrayBuffer &buffer, uint32_t offset, uint32_t length);
- Uint8Array(char *buffer, uint32_t size);
+ Uint8Array(const char *buffer, uint32_t size);
ArrayBuffer buffer() const;
uint32_t length() const;
void set(const Uint8Array &source);
+ Uint8Array subarray(uint32_t begin, uint32_t end);
void copyTo(char *destination) const;
+ QByteArray copyToQByteArray() const;
+
static void copy(char *destination, const Uint8Array &source);
+ static Uint8Array copyFrom(const char *buffer, uint32_t size);
+ static Uint8Array copyFrom(const QByteArray &buffer);
+ emscripten::val val() const;
+
private:
static emscripten::val heap_();
static emscripten::val constructor_();
emscripten::val m_uint8Array = emscripten::val::undefined();
};
- class EventCallback
+ class Q_CORE_EXPORT EventCallback
+ {
+ public:
+ EventCallback() = default;
+ ~EventCallback();
+ EventCallback(EventCallback const&) = delete;
+ EventCallback& operator=(EventCallback const&) = delete;
+ EventCallback(emscripten::val element, const std::string &name,
+ const std::function<void(emscripten::val)> &fn);
+
+ private:
+ emscripten::val m_element = emscripten::val::undefined();
+ std::string m_eventName;
+ std::unique_ptr<std::function<void(emscripten::val)>> m_handler;
+ emscripten::val m_eventListener = emscripten::val::undefined();
+ };
+
+ struct PromiseCallbacks
+ {
+ std::function<void(emscripten::val)> thenFunc;
+ std::function<void(emscripten::val)> catchFunc;
+ std::function<void()> finallyFunc;
+ };
+
+ namespace Promise {
+ void Q_CORE_EXPORT adoptPromise(emscripten::val promise, PromiseCallbacks callbacks);
+
+ template<typename... Args>
+ void make(emscripten::val target,
+ QString methodName,
+ PromiseCallbacks callbacks,
+ Args... args)
+ {
+ emscripten::val promiseObject = target.call<emscripten::val>(
+ methodName.toStdString().c_str(), std::forward<Args>(args)...);
+ if (promiseObject.isUndefined() || promiseObject["constructor"]["name"].as<std::string>() != "Promise") {
+ qFatal("This function did not return a promise");
+ }
+
+ adoptPromise(std::move(promiseObject), std::move(callbacks));
+ }
+
+ void Q_CORE_EXPORT all(std::vector<emscripten::val> promises, PromiseCallbacks callbacks);
+ };
+
+ template<class F>
+ decltype(auto) bindForever(F wrappedCallback)
+ {
+ return wrappedCallback;
+ }
+
+ class Q_CORE_EXPORT BlobIODevice: public QIODevice
{
public:
- EventCallback(emscripten::val element, const std::string &name, const std::function<void ()> &fn);
- static void activate(emscripten::val event);
+ BlobIODevice(Blob blob);
+ bool open(QIODeviceBase::OpenMode mode) override;
+ bool isSequential() const override;
+ qint64 size() const override;
+ bool seek(qint64 pos) override;
+
+ protected:
+ qint64 readData(char *data, qint64 maxSize) override;
+ qint64 writeData(const char *, qint64) override;
+
private:
- static std::string contextPropertyName(const std::string &eventName);
- std::function<void ()> m_fn;
+ Blob m_blob;
};
+
+ class Uint8ArrayIODevice: public QIODevice
+ {
+ public:
+ Uint8ArrayIODevice(Uint8Array array);
+ bool open(QIODevice::OpenMode mode) override;
+ bool isSequential() const override;
+ qint64 size() const override;
+ bool seek(qint64 pos) override;
+
+ protected:
+ qint64 readData(char *data, qint64 maxSize) override;
+ qint64 writeData(const char *data, qint64 size) override;
+
+ private:
+ Uint8Array m_array;
+ };
+
+ inline emscripten::val window()
+ {
+ static emscripten::val savedWindow = emscripten::val::global("window");
+ return savedWindow;
+ }
+
+ bool haveAsyncify();
+ bool Q_CORE_EXPORT haveJspi();
+ bool canBlockCallingThread();
+
+ struct CancellationFlag
+ {
+ };
+
+#if QT_CONFIG(thread)
+ template<class T>
+ T proxyCall(std::function<T()> task, emscripten::ProxyingQueue *queue)
+ {
+ T result;
+ queue->proxySync(emscripten_main_runtime_thread_id(),
+ [task, result = &result]() { *result = task(); });
+ return result;
+ }
+
+ template<>
+ inline void proxyCall<void>(std::function<void()> task, emscripten::ProxyingQueue *queue)
+ {
+ queue->proxySync(emscripten_main_runtime_thread_id(), task);
+ }
+
+ template<class T>
+ T runTaskOnMainThread(std::function<T()> task, emscripten::ProxyingQueue *queue)
+ {
+ return emscripten_is_main_runtime_thread() ? task() : proxyCall<T>(std::move(task), queue);
+ }
+
+ template<class T>
+ T runTaskOnMainThread(std::function<T()> task)
+ {
+ emscripten::ProxyingQueue singleUseQueue;
+ return runTaskOnMainThread<T>(task, &singleUseQueue);
+ }
+
+#else
+ template<class T>
+ T runTaskOnMainThread(std::function<T()> task)
+ {
+ return task();
+ }
+#endif // QT_CONFIG(thread)
+
}
QT_END_NAMESPACE