(file, offset, len)
| 21 | // Get a promise that fetches the data and stores it in JS memory (if it has |
| 22 | // not already been fetched). |
| 23 | async function getFileRange(file, offset, len) { |
| 24 | var url = ''; |
| 25 | var fileUrl_p = __wasmfs_fetch_get_file_url(file); |
| 26 | var fileUrl = UTF8ToString(fileUrl_p); |
| 27 | var isAbs = fileUrl.indexOf('://') !== -1; |
| 28 | if (isAbs) { |
| 29 | url = fileUrl; |
| 30 | } else { |
| 31 | try { |
| 32 | var u = new URL(fileUrl, self.location.origin); |
| 33 | url = u.toString(); |
| 34 | } catch (_e) { |
| 35 | throw {status: 404}; |
| 36 | } |
| 37 | } |
| 38 | var chunkSize = __wasmfs_fetch_get_chunk_size(file); |
| 39 | offset ??= 0; |
| 40 | len ??= chunkSize; |
| 41 | // In which chunk does the seeked range start? E.g., 5-14 with chunksize 8 will start in chunk 0. |
| 42 | if (!(file in wasmFS$JSMemoryRanges)) { |
| 43 | var fileInfo = await fetch(url, {method:'HEAD', headers:{'Range': 'bytes=0-'}}); |
| 44 | if (fileInfo.ok && |
| 45 | fileInfo.headers.has('Content-Length') && |
| 46 | fileInfo.headers.get('Accept-Ranges') == 'bytes' && |
| 47 | (parseInt(fileInfo.headers.get('Content-Length'), 10) > chunkSize*2)) { |
| 48 | var size = parseInt(fileInfo.headers.get('Content-Length'), 10); |
| 49 | wasmFS$JSMemoryRanges[file] = { |
| 50 | size, |
| 51 | chunks: [], |
| 52 | chunkSize: chunkSize |
| 53 | }; |
| 54 | len = Math.min(len, size-offset); |
| 55 | } else { |
| 56 | // may as well/forced to download the whole file |
| 57 | var wholeFileReq = await fetch(url); |
| 58 | if (!wholeFileReq.ok) { |
| 59 | throw wholeFileReq; |
| 60 | } |
| 61 | var wholeFileData = new Uint8Array(await wholeFileReq.arrayBuffer()); |
| 62 | wasmFS$JSMemoryRanges[file] = { |
| 63 | size: wholeFileData.byteLength, |
| 64 | chunks: [wholeFileData], |
| 65 | chunkSize: wholeFileData.byteLength |
| 66 | }; |
| 67 | return; |
| 68 | } |
| 69 | } |
| 70 | var firstChunk = (offset / chunkSize) | 0; |
| 71 | // In which chunk does the seeked range end? E.g., 5-14 with chunksize 8 will end in chunk 1, as will 5-16 (since byte 16 isn't requested). |
| 72 | // This will always give us a chunk >= firstChunk since len > 0. |
| 73 | var lastChunk = ((offset+len-1) / chunkSize) | 0; |
| 74 | var allPresent = true; |
| 75 | var i; |
| 76 | // Do we have all the chunks already? If so, we don't need to do any fetches. |
| 77 | for (i = firstChunk; i <= lastChunk; i++) { |
| 78 | if (!wasmFS$JSMemoryRanges[file].chunks[i]) { |
| 79 | allPresent = false; |
| 80 | break; |
no test coverage detected