blob: 48bf2a659883398557065fd51e05f8d3ed665c59 [file] [log] [blame]
/**
* @license
* Copyright 2022 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
mergeInto(LibraryManager.library, {
// Fetch backend: On first access of the file (either a read or a getSize), it
// will fetch() the data from the network asynchronously. Otherwise, after
// that fetch it behaves just like JSFile (and it reuses the code from there).
_wasmfs_create_fetch_backend_js__deps: [
'$wasmFS$backends',
'$wasmFS$JSMemoryFiles',
'_wasmfs_create_js_file_backend_js',
],
_wasmfs_create_fetch_backend_js: async function(backend) {
// Get a promise that fetches the data and stores it in JS memory (if it has
// not already been fetched).
async function getFile(file) {
if (wasmFS$JSMemoryFiles[file]) {
// The data is already here, so nothing to do before we continue on to
// the actual read below.
return Promise.resolve();
}
// This is the first time we want the file's data.
var url = '';
var fileUrl_p = __wasmfs_fetch_get_file_path(file);
var fileUrl = UTF8ToString(fileUrl_p);
var isAbs = fileUrl.indexOf('://') !== -1;
if (isAbs) {
url = fileUrl;
} else {
try {
var u = new URL(fileUrl, self.location.origin);
url = u.toString();
} catch (e) {
}
}
var response = await fetch(url);
if (response.ok) {
var buffer = await response['arrayBuffer']();
wasmFS$JSMemoryFiles[file] = new Uint8Array(buffer);
} else {
throw response;
}
}
// Start with the normal JSFile operations. This sets
// wasmFS$backends[backend]
// which we will then augment.
__wasmfs_create_js_file_backend_js(backend);
// Add the async operations on top.
var jsFileOps = wasmFS$backends[backend];
wasmFS$backends[backend] = {
// alloc/free operations are not actually async. Just forward to the
// parent class, but we must return a Promise as the caller expects.
allocFile: async (file) => {
jsFileOps.allocFile(file);
return Promise.resolve();
},
freeFile: async (file) => {
jsFileOps.freeFile(file);
return Promise.resolve();
},
write: async (file, buffer, length, offset) => {
abort("TODO: file writing in fetch backend? read-only for now");
},
// read/getSize fetch the data, then forward to the parent class.
read: async (file, buffer, length, offset) => {
try {
await getFile(file);
} catch (response) {
return response.status === 404 ? -{{{ cDefine('ENOENT') }}} : -{{{ cDefine('EBADF') }}};
}
return jsFileOps.read(file, buffer, length, offset);
},
getSize: async (file) => {
try {
await getFile(file);
} catch (response) {}
return jsFileOps.getSize(file);
},
};
},
});