diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2021-11-09 13:10:13 +0100 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2021-11-26 10:04:31 +0100 |
commit | f92d4ffeade1a95106dc127e3b686cc639a46de4 (patch) | |
tree | 67bc5ffbadbae214ad6015bff81df53f93100667 /src/corelib/platform | |
parent | 59600a514ba99ed62b46237d8f160dea84474190 (diff) |
wasm: Move streamFile() to qstdweb
This function is useful also outside of local file access,
for example when reading clipboard (file) content.
Change-Id: I132546deb6df2969467051c348c05d9331d2cfd2
Reviewed-by: David Skoland <david.skoland@qt.io>
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Diffstat (limited to 'src/corelib/platform')
-rw-r--r-- | src/corelib/platform/wasm/qstdweb.cpp | 45 | ||||
-rw-r--r-- | src/corelib/platform/wasm/qstdweb_p.h | 2 |
2 files changed, 47 insertions, 0 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(); |