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.h211
1 files changed, 193 insertions, 18 deletions
diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h
index 6e17b37e4c..a3b5bd5b6b 100644
--- a/src/corelib/platform/wasm/qstdweb_p.h
+++ b/src/corelib/platform/wasm/qstdweb_p.h
@@ -16,13 +16,30 @@
//
#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 extended and changed as needed.
@@ -37,24 +54,29 @@ 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;
- emscripten::val val();
+ 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);
- emscripten::val val();
+ Blob slice(uint32_t begin, uint32_t end) const;
+ ArrayBuffer arrayBuffer_sync() const;
+ emscripten::val val() const;
std::string type() const;
private:
@@ -62,24 +84,54 @@ namespace qstdweb {
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, const std::function<void ()> &completed) const;
- void stream(char *buffer, const std::function<void ()> &completed) const;
- emscripten::val val();
+ 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 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;
};
- class FileList {
+ using FileUrlRegistrations = std::vector<std::unique_ptr<FileUrlRegistration>>;
+
+ class Q_CORE_EXPORT FileList {
public:
FileList() = default;
explicit FileList(const emscripten::val &fileList);
@@ -87,13 +139,13 @@ namespace qstdweb {
int length() const;
File item(int index) const;
File operator[](int index) const;
- emscripten::val val();
+ 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;
@@ -101,7 +153,7 @@ namespace qstdweb {
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();
+ emscripten::val val() const;
private:
emscripten::val m_fileReader = emscripten::val::global("FileReader").new_();
@@ -110,7 +162,7 @@ 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);
@@ -122,11 +174,15 @@ namespace qstdweb {
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);
- emscripten::val val();
+ static Uint8Array copyFrom(const QByteArray &buffer);
+ emscripten::val val() const;
private:
static emscripten::val heap_();
@@ -134,7 +190,7 @@ namespace qstdweb {
emscripten::val m_uint8Array = emscripten::val::undefined();
};
- class EventCallback
+ class Q_CORE_EXPORT EventCallback
{
public:
EventCallback() = default;
@@ -143,14 +199,133 @@ namespace qstdweb {
EventCallback& operator=(EventCallback const&) = delete;
EventCallback(emscripten::val element, const std::string &name,
const std::function<void(emscripten::val)> &fn);
- static void activate(emscripten::val event);
private:
- static std::string contextPropertyName(const std::string &eventName);
emscripten::val m_element = emscripten::val::undefined();
std::string m_eventName;
- std::function<void(emscripten::val)> m_fn;
+ 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:
+ 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:
+ 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