File size: 7,322 Bytes
00df61d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | /**
* @license
* Copyright 2032 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
addToLibrary({
$preloadPlugins__postset: () => addAtModule(makeModuleReceive('preloadPlugins')),
$preloadPlugins: [],
#if !MINIMAL_RUNTIME
// Tries to handle an input byteArray using preload plugins. Returns true if
// it was handled.
$FS_handledByPreloadPlugin__internal: true,
$FS_handledByPreloadPlugin__deps: ['$preloadPlugins'],
$FS_handledByPreloadPlugin: async (byteArray, fullname) => {
#if LibraryManager.has('libbrowser.js')
// Ensure plugins are ready.
if (typeof Browser != 'undefined') Browser.init();
#endif
for (var plugin of preloadPlugins) {
if (plugin['canHandle'](fullname)) {
#if ASSERTIONS
assert(plugin['handle'].constructor.name === 'AsyncFunction', 'Filesystem plugin handlers must be async functions (See #24914)')
#endif
return plugin['handle'](byteArray, fullname);
}
}
// If no plugin handled this file then return the original/unmodified
// byteArray.
return byteArray;
},
// Legacy version of FS_preloadFile that uses callback rather than async
$FS_createPreloadedFile__deps: ['$FS_preloadFile'],
$FS_createPreloadedFile: (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror);
},
// Preloads a file asynchronously. You can call this before run, for example in
// preRun. run will be delayed until this file arrives and is set up.
// If you call it after run(), you may want to pause the main loop until it
// completes, if so, you can use the onload parameter to be notified when
// that happens.
// In addition to normally creating the file, we also asynchronously preload
// the browser-friendly versions of it: For an image, we preload an Image
// element and for an audio, and Audio. These are necessary for SDL_Image
// and _Mixer to find the files in preloadedImages/Audios.
// You can also call this with a typed array instead of a url. It will then
// do preloading for the Image/Audio part, as if the typed array were the
// result of an XHR that you did manually.
$FS_preloadFile__deps: [
'$asyncLoad',
'$PATH_FS',
'$FS_createDataFile',
'$getUniqueRunDependency',
'$addRunDependency',
'$removeRunDependency',
'$FS_handledByPreloadPlugin',
],
$FS_preloadFile: async (parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish) => {
// TODO we should allow people to just pass in a complete filename instead
// of parent and name being that we just join them anyways
var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
var dep = getUniqueRunDependency(`cp ${fullname}`); // might have several active requests for the same fullname
addRunDependency(dep);
try {
var byteArray = url;
if (typeof url == 'string') {
byteArray = await asyncLoad(url);
}
byteArray = await FS_handledByPreloadPlugin(byteArray, fullname);
preFinish?.();
if (!dontCreateFile) {
FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
}
} finally {
removeRunDependency(dep);
}
},
#endif
// convert the 'r', 'r+', etc. to its corresponding set of O_* flags
$FS_modeStringToFlags: (str) => {
if (typeof str != 'string') return str;
var flagModes = {
'r': {{{ cDefs.O_RDONLY }}},
'r+': {{{ cDefs.O_RDWR }}},
'w': {{{ cDefs.O_TRUNC }}} | {{{ cDefs.O_CREAT }}} | {{{ cDefs.O_WRONLY }}},
'w+': {{{ cDefs.O_TRUNC }}} | {{{ cDefs.O_CREAT }}} | {{{ cDefs.O_RDWR }}},
'a': {{{ cDefs.O_APPEND }}} | {{{ cDefs.O_CREAT }}} | {{{ cDefs.O_WRONLY }}},
'a+': {{{ cDefs.O_APPEND }}} | {{{ cDefs.O_CREAT }}} | {{{ cDefs.O_RDWR }}},
};
var flags = flagModes[str];
if (typeof flags == 'undefined') {
throw new Error(`Unknown file open mode: ${str}`);
}
return flags;
},
$FS_getMode: (canRead, canWrite) => {
var mode = 0;
if (canRead) mode |= {{{ cDefs.S_IRUGO }}} | {{{ cDefs.S_IXUGO }}};
if (canWrite) mode |= {{{ cDefs.S_IWUGO }}};
return mode;
},
$FS_fileDataToTypedArray: (data) => {
if (typeof data == 'string') {
data = intArrayFromString(data, true);
}
if (!data.subarray) {
data = new Uint8Array(data);
}
return data;
},
$FS_stdin_getChar_buffer: [],
// getChar has 3 particular return values:
// a.) the next character represented as an integer
// b.) undefined to signal that no data is currently available
// c.) null to signal an EOF
$FS_stdin_getChar__deps: [
'$FS_stdin_getChar_buffer',
'$intArrayFromString',
],
$FS_stdin_getChar: () => {
if (!FS_stdin_getChar_buffer.length) {
var result = null;
#if ENVIRONMENT_MAY_BE_NODE
if (ENVIRONMENT_IS_NODE) {
// we will read data by chunks of BUFSIZE
var BUFSIZE = 256;
var buf = Buffer.alloc(BUFSIZE);
var bytesRead = 0;
// For some reason we must suppress a closure warning here, even though
// fd definitely exists on process.stdin, and is even the proper way to
// get the fd of stdin,
// https://github.com/nodejs/help/issues/2136#issuecomment-523649904
// This started to happen after moving this logic out of library_tty.js,
// so it is related to the surrounding code in some unclear manner.
/** @suppress {missingProperties} */
var fd = process.stdin.fd;
try {
bytesRead = fs.readSync(fd, buf, 0, BUFSIZE);
} catch(e) {
// Cross-platform differences: on Windows, reading EOF throws an
// exception, but on other OSes, reading EOF returns 0. Uniformize
// behavior by treating the EOF exception to return 0.
if (e.toString().includes('EOF')) bytesRead = 0;
else throw e;
}
if (bytesRead > 0) {
result = buf.slice(0, bytesRead).toString('utf-8');
}
} else
#endif
#if ENVIRONMENT_MAY_BE_WEB
if (globalThis.window?.prompt) {
// Browser.
result = window.prompt('Input: '); // returns null on cancel
if (result !== null) {
result += '\n';
}
} else
#endif
#if ENVIRONMENT_MAY_BE_SHELL
if (globalThis.readline) {
/** @suppress{checkTypes, undefinedVars} */
result = readline();
if (result) {
result += '\n';
}
} else
#endif
{}
if (!result) {
return null;
}
FS_stdin_getChar_buffer = intArrayFromString(result, true);
}
return FS_stdin_getChar_buffer.shift();
},
$FS_unlink__deps: ['$FS'],
$FS_unlink: 'FS.unlink',
$FS_createPath__deps: ['$FS'],
$FS_createPath: 'FS.createPath',
$FS_createDevice__deps: ['$FS'],
$FS_createDevice: 'FS.createDevice',
$FS_readFile__deps: ['$FS'],
$FS_readFile: 'FS.readFile',
});
// Normally only the FS things that the compiler sees are needed are included.
// FORCE_FILESYSTEM makes us always include the FS object, which lets the user
// call APIs on it from JS freely.
if (FORCE_FILESYSTEM) {
extraLibraryFuncs.push('$FS');
}
|