11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ciconst { Readable } = require('stream'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci{ 81cb0ef41Sopenharmony_ci // Check that strings are saved as Buffer 91cb0ef41Sopenharmony_ci const readable = new Readable({ read() {} }); 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci const string = 'abc'; 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci readable.on('data', common.mustCall((chunk) => { 141cb0ef41Sopenharmony_ci assert(Buffer.isBuffer(chunk)); 151cb0ef41Sopenharmony_ci assert.strictEqual(chunk.toString('utf8'), string); 161cb0ef41Sopenharmony_ci }, 1)); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci readable.unshift(string); 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci} 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci{ 231cb0ef41Sopenharmony_ci // Check that data goes at the beginning 241cb0ef41Sopenharmony_ci const readable = new Readable({ read() {} }); 251cb0ef41Sopenharmony_ci const unshift = 'front'; 261cb0ef41Sopenharmony_ci const push = 'back'; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci const expected = [unshift, push]; 291cb0ef41Sopenharmony_ci readable.on('data', common.mustCall((chunk) => { 301cb0ef41Sopenharmony_ci assert.strictEqual(chunk.toString('utf8'), expected.shift()); 311cb0ef41Sopenharmony_ci }, 2)); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci readable.push(push); 351cb0ef41Sopenharmony_ci readable.unshift(unshift); 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci{ 391cb0ef41Sopenharmony_ci // Check that buffer is saved with correct encoding 401cb0ef41Sopenharmony_ci const readable = new Readable({ read() {} }); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci const encoding = 'base64'; 431cb0ef41Sopenharmony_ci const string = Buffer.from('abc').toString(encoding); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci readable.on('data', common.mustCall((chunk) => { 461cb0ef41Sopenharmony_ci assert.strictEqual(chunk.toString(encoding), string); 471cb0ef41Sopenharmony_ci }, 1)); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci readable.unshift(string, encoding); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci} 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci{ 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci const streamEncoding = 'base64'; 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci function checkEncoding(readable) { 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // chunk encodings 601cb0ef41Sopenharmony_ci const encodings = ['utf8', 'binary', 'hex', 'base64']; 611cb0ef41Sopenharmony_ci const expected = []; 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci readable.on('data', common.mustCall((chunk) => { 641cb0ef41Sopenharmony_ci const { encoding, string } = expected.pop(); 651cb0ef41Sopenharmony_ci assert.strictEqual(chunk.toString(encoding), string); 661cb0ef41Sopenharmony_ci }, encodings.length)); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci for (const encoding of encodings) { 691cb0ef41Sopenharmony_ci const string = 'abc'; 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci // If encoding is the same as the state.encoding the string is 721cb0ef41Sopenharmony_ci // saved as is 731cb0ef41Sopenharmony_ci const expect = encoding !== streamEncoding ? 741cb0ef41Sopenharmony_ci Buffer.from(string, encoding).toString(streamEncoding) : string; 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci expected.push({ encoding, string: expect }); 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci readable.unshift(string, encoding); 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci const r1 = new Readable({ read() {} }); 831cb0ef41Sopenharmony_ci r1.setEncoding(streamEncoding); 841cb0ef41Sopenharmony_ci checkEncoding(r1); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci const r2 = new Readable({ read() {}, encoding: streamEncoding }); 871cb0ef41Sopenharmony_ci checkEncoding(r2); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci} 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci{ 921cb0ef41Sopenharmony_ci // Both .push & .unshift should have the same behaviour 931cb0ef41Sopenharmony_ci // When setting an encoding, each chunk should be emitted with that encoding 941cb0ef41Sopenharmony_ci const encoding = 'base64'; 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci function checkEncoding(readable) { 971cb0ef41Sopenharmony_ci const string = 'abc'; 981cb0ef41Sopenharmony_ci readable.on('data', common.mustCall((chunk) => { 991cb0ef41Sopenharmony_ci assert.strictEqual(chunk, Buffer.from(string).toString(encoding)); 1001cb0ef41Sopenharmony_ci }, 2)); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci readable.push(string); 1031cb0ef41Sopenharmony_ci readable.unshift(string); 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci const r1 = new Readable({ read() {} }); 1071cb0ef41Sopenharmony_ci r1.setEncoding(encoding); 1081cb0ef41Sopenharmony_ci checkEncoding(r1); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci const r2 = new Readable({ read() {}, encoding }); 1111cb0ef41Sopenharmony_ci checkEncoding(r2); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci} 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci{ 1161cb0ef41Sopenharmony_ci // Check that ObjectMode works 1171cb0ef41Sopenharmony_ci const readable = new Readable({ objectMode: true, read() {} }); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci const chunks = ['a', 1, {}, []]; 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci readable.on('data', common.mustCall((chunk) => { 1221cb0ef41Sopenharmony_ci assert.strictEqual(chunk, chunks.pop()); 1231cb0ef41Sopenharmony_ci }, chunks.length)); 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci for (const chunk of chunks) { 1261cb0ef41Sopenharmony_ci readable.unshift(chunk); 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci} 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci{ 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci // Should not throw: https://github.com/nodejs/node/issues/27192 1331cb0ef41Sopenharmony_ci const highWaterMark = 50; 1341cb0ef41Sopenharmony_ci class ArrayReader extends Readable { 1351cb0ef41Sopenharmony_ci constructor(opt) { 1361cb0ef41Sopenharmony_ci super({ highWaterMark }); 1371cb0ef41Sopenharmony_ci // The error happened only when pushing above hwm 1381cb0ef41Sopenharmony_ci this.buffer = new Array(highWaterMark * 2).fill(0).map(String); 1391cb0ef41Sopenharmony_ci } 1401cb0ef41Sopenharmony_ci _read(size) { 1411cb0ef41Sopenharmony_ci while (this.buffer.length) { 1421cb0ef41Sopenharmony_ci const chunk = this.buffer.shift(); 1431cb0ef41Sopenharmony_ci if (!this.buffer.length) { 1441cb0ef41Sopenharmony_ci this.push(chunk); 1451cb0ef41Sopenharmony_ci this.push(null); 1461cb0ef41Sopenharmony_ci return true; 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci if (!this.push(chunk)) 1491cb0ef41Sopenharmony_ci return; 1501cb0ef41Sopenharmony_ci } 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci } 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci function onRead() { 1551cb0ef41Sopenharmony_ci while (null !== (stream.read())) { 1561cb0ef41Sopenharmony_ci // Remove the 'readable' listener before unshifting 1571cb0ef41Sopenharmony_ci stream.removeListener('readable', onRead); 1581cb0ef41Sopenharmony_ci stream.unshift('a'); 1591cb0ef41Sopenharmony_ci stream.on('data', (chunk) => { 1601cb0ef41Sopenharmony_ci console.log(chunk.length); 1611cb0ef41Sopenharmony_ci }); 1621cb0ef41Sopenharmony_ci break; 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci } 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci const stream = new ArrayReader(); 1671cb0ef41Sopenharmony_ci stream.once('readable', common.mustCall(onRead)); 1681cb0ef41Sopenharmony_ci stream.on('end', common.mustCall()); 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci} 171