summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/platform/wasm/qstdweb.cpp45
-rw-r--r--src/corelib/platform/wasm/qstdweb_p.h2
-rw-r--r--src/gui/platform/wasm/qwasmlocalfileaccess.cpp40
3 files changed, 48 insertions, 39 deletions
diff --git a/src/corelib/platform/wasm/qstdweb.cpp b/src/corelib/platform/wasm/qstdweb.cpp
index 198ce897ca..789ceda6ab 100644
--- a/src/corelib/platform/wasm/qstdweb.cpp
+++ b/src/corelib/platform/wasm/qstdweb.cpp
@@ -95,6 +95,51 @@ uint64_t File::size() const
return uint64_t(m_file["size"].as<uint53_t>());
}
+// Streams partial file content into the given buffer asynchronously. The completed
+// callback is called on completion.
+void File::stream(uint32_t offset, uint32_t length, char *buffer, const std::function<void ()> &completed) const
+{
+ // Read file in chunks in order to avoid holding two copies in memory at the same time
+ const uint32_t chunkSize = 256 * 1024;
+ const uint32_t end = offset + length;
+ // assert end < file.size
+ auto fileReader = std::make_shared<qstdweb::FileReader>();
+
+ // "this" is valid now, but may not be by the time the chunkCompleted callback
+ // below is made. Make a copy of the file handle.
+ const File fileHandle = *this;
+ auto chunkCompleted = std::make_shared<std::function<void (uint32_t, char *buffer)>>();
+ *chunkCompleted = [=](uint32_t chunkBegin, char *chunkBuffer) mutable {
+
+ // Copy current chunk from JS memory to Wasm memory
+ qstdweb::ArrayBuffer result = fileReader->result();
+ qstdweb::Uint8Array(result).copyTo(chunkBuffer);
+
+ // Read next chunk if not at buffer end
+ uint32_t nextChunkBegin = std::min(chunkBegin + result.byteLength(), end);
+ uint32_t nextChunkEnd = std::min(nextChunkBegin + chunkSize, end);
+ if (nextChunkBegin == end) {
+ completed();
+ chunkCompleted.reset();
+ return;
+ }
+ char *nextChunkBuffer = chunkBuffer + result.byteLength();
+ fileReader->onLoad([=]() { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); });
+ qstdweb::Blob blob = fileHandle.slice(nextChunkBegin, nextChunkEnd);
+ fileReader->readAsArrayBuffer(blob);
+ };
+
+ // Read first chunk. First iteration is a dummy iteration with no available data.
+ (*chunkCompleted)(offset, buffer);
+}
+
+// Streams file content into the given buffer asynchronously. The completed
+// callback is called on completion.
+void File::stream(char *buffer, const std::function<void ()> &completed) const
+{
+ stream(0, size(), buffer, completed);
+}
+
FileList::FileList(const emscripten::val &fileList)
:m_fileList(fileList)
{
diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h
index 86c9cdcabd..ff83c73dd5 100644
--- a/src/corelib/platform/wasm/qstdweb_p.h
+++ b/src/corelib/platform/wasm/qstdweb_p.h
@@ -99,6 +99,8 @@ namespace qstdweb {
Blob slice(uint64_t begin, uint64_t end) const;
std::string name() const;
uint64_t size() 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;
private:
emscripten::val m_file = emscripten::val::undefined();
diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
index a5460f0ba7..e810a1ad8e 100644
--- a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
+++ b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
@@ -48,44 +48,6 @@ QT_BEGIN_NAMESPACE
namespace QWasmLocalFileAccess {
-void streamFile(const qstdweb::File &file, uint32_t offset, uint32_t length, char *buffer, const std::function<void ()> &completed)
-{
- // Read file in chunks in order to avoid holding two copies in memory at the same time
- const uint32_t chunkSize = 256 * 1024;
- const uint32_t end = offset + length;
- // assert end < file.size
- auto fileReader = std::make_shared<qstdweb::FileReader>();
-
- auto chunkCompleted = std::make_shared<std::function<void (uint32_t, char *buffer)>>();
- *chunkCompleted = [=](uint32_t chunkBegin, char *chunkBuffer) mutable {
-
- // Copy current chunk from JS memory to Wasm memory
- qstdweb::ArrayBuffer result = fileReader->result();
- qstdweb::Uint8Array(result).copyTo(chunkBuffer);
-
- // Read next chunk if not at buffer end
- uint32_t nextChunkBegin = std::min(chunkBegin + result.byteLength(), end);
- uint32_t nextChunkEnd = std::min(nextChunkBegin + chunkSize, end);
- if (nextChunkBegin == end) {
- completed();
- chunkCompleted.reset();
- return;
- }
- char *nextChunkBuffer = chunkBuffer + result.byteLength();
- fileReader->onLoad([=]() { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); });
- qstdweb::Blob blob = file.slice(nextChunkBegin, nextChunkEnd);
- fileReader->readAsArrayBuffer(blob);
- };
-
- // Read first chunk. First iteration is a dummy iteration with no available data.
- (*chunkCompleted)(offset, buffer);
-}
-
-void streamFile(const qstdweb::File &file, char *buffer, const std::function<void ()> &completed)
-{
- streamFile(file, 0, file.size(), buffer, completed);
-}
-
void readFiles(const qstdweb::FileList &fileList,
const std::function<char *(uint64_t size, const std::string name)> &acceptFile,
const std::function<void ()> &fileDataReady)
@@ -109,7 +71,7 @@ void readFiles(const qstdweb::FileList &fileList,
}
// Read file data into caller-provided buffer
- streamFile(file, buffer, [=]() {
+ file.stream(buffer, [=]() {
fileDataReady();
(*readFile)(fileIndex + 1);
});