large-pipeto.js (2831B)
1 const { AppConstants } = ChromeUtils.importESModule( 2 "resource://gre/modules/AppConstants.sys.mjs" 3 ); 4 5 // Stamp an array buffer with a pattern; verified by verify_chunk below. 6 function init(array) { 7 for (var i = 0; i < array.length; i++) { 8 array[i] = i % 256; 9 } 10 } 11 12 // The construction of the file below ends up with 12 instances 13 // of the array buffer -- we want this to be larger than 2**32 bytes 14 // to exercise potential truncation of nsIInputStream::Read's count 15 // parameter. 16 const ABLENGTH = (2 ** 32 + 8) / 12; 17 18 // Get a large file (bigger than 2GB!) 19 function get_file() { 20 const array = new ArrayBuffer(ABLENGTH); 21 const buff = new Uint8Array(array); 22 23 // Stamp with pattern. 24 init(buff); 25 26 const blob = new Blob([buff, buff], {}); 27 return new File([blob, blob, blob, blob, blob, blob], {}); 28 } 29 30 // Verify that the chunks the stream recieve correspond to the initialization 31 function verify_chunk(chunk, verification_state) { 32 for (var j = 0; j < chunk.length; j++) { 33 // If we don't match the fill pattern. 34 if (chunk[j] != verification_state.expected) { 35 // we ran out of array buffer; so we should be looking at the first byte of the array again. 36 if ( 37 verification_state.total_index % ABLENGTH != 0 || 38 chunk[j] != 0 /* ASSUME THAT THE INITIALIZATION OF THE BUFFER IS ZERO */ 39 ) { 40 throw new Error( 41 `Mismatch: chunk[${j}] (${chunk[j]}) != ${verification_state.expected} (total_index ${verification_state.total_index})` 42 ); 43 } 44 // Reset the fill expectation to 1 for next round. 45 verification_state.expected = 1; 46 } else { 47 // We are inside regular fill section 48 verification_state.expected = (verification_state.expected + 1) % 256; 49 } 50 verification_state.total_index++; 51 } 52 } 53 54 // Pipe To Testing: Win32 can't handle the file size created in this test and OOMs. 55 add_task( 56 { 57 skip_if: () => AppConstants.platform == "win" && !Services.appinfo.is64Bit, 58 }, 59 async () => { 60 var chunk_verification_state = { 61 expected: 0, 62 total_index: 0, 63 }; 64 65 const file = get_file(); 66 67 await file.stream().pipeTo( 68 new WritableStream({ 69 write(chunk) { 70 verify_chunk(chunk, chunk_verification_state); 71 }, 72 }) 73 ); 74 } 75 ); 76 77 // Do the same test as above, but this time don't use pipeTo. 78 add_task( 79 { 80 skip_if: () => AppConstants.platform == "win" && !Services.appinfo.is64Bit, 81 }, 82 async () => { 83 var file = get_file(); 84 85 var chunk_verification_state = { 86 expected: 0, 87 total_index: 0, 88 }; 89 90 var streamReader = file.stream().getReader(); 91 92 while (true) { 93 var res = await streamReader.read(); 94 if (res.done) { 95 break; 96 } 97 var chunk = res.value; 98 verify_chunk(chunk, chunk_verification_state); 99 } 100 } 101 );