11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayIsArray, 51cb0ef41Sopenharmony_ci ObjectSetPrototypeOf, 61cb0ef41Sopenharmony_ci} = primordials; 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ciconst EE = require('events'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cifunction Stream(opts) { 111cb0ef41Sopenharmony_ci EE.call(this, opts); 121cb0ef41Sopenharmony_ci} 131cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Stream.prototype, EE.prototype); 141cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Stream, EE); 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciStream.prototype.pipe = function(dest, options) { 171cb0ef41Sopenharmony_ci const source = this; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci function ondata(chunk) { 201cb0ef41Sopenharmony_ci if (dest.writable && dest.write(chunk) === false && source.pause) { 211cb0ef41Sopenharmony_ci source.pause(); 221cb0ef41Sopenharmony_ci } 231cb0ef41Sopenharmony_ci } 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci source.on('data', ondata); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci function ondrain() { 281cb0ef41Sopenharmony_ci if (source.readable && source.resume) { 291cb0ef41Sopenharmony_ci source.resume(); 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci dest.on('drain', ondrain); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci // If the 'end' option is not supplied, dest.end() will be called when 361cb0ef41Sopenharmony_ci // source gets the 'end' or 'close' events. Only dest.end() once. 371cb0ef41Sopenharmony_ci if (!dest._isStdio && (!options || options.end !== false)) { 381cb0ef41Sopenharmony_ci source.on('end', onend); 391cb0ef41Sopenharmony_ci source.on('close', onclose); 401cb0ef41Sopenharmony_ci } 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci let didOnEnd = false; 431cb0ef41Sopenharmony_ci function onend() { 441cb0ef41Sopenharmony_ci if (didOnEnd) return; 451cb0ef41Sopenharmony_ci didOnEnd = true; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci dest.end(); 481cb0ef41Sopenharmony_ci } 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci function onclose() { 521cb0ef41Sopenharmony_ci if (didOnEnd) return; 531cb0ef41Sopenharmony_ci didOnEnd = true; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci if (typeof dest.destroy === 'function') dest.destroy(); 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci // Don't leave dangling pipes when there are errors. 591cb0ef41Sopenharmony_ci function onerror(er) { 601cb0ef41Sopenharmony_ci cleanup(); 611cb0ef41Sopenharmony_ci if (EE.listenerCount(this, 'error') === 0) { 621cb0ef41Sopenharmony_ci this.emit('error', er); 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci prependListener(source, 'error', onerror); 671cb0ef41Sopenharmony_ci prependListener(dest, 'error', onerror); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci // Remove all the event listeners that were added. 701cb0ef41Sopenharmony_ci function cleanup() { 711cb0ef41Sopenharmony_ci source.removeListener('data', ondata); 721cb0ef41Sopenharmony_ci dest.removeListener('drain', ondrain); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci source.removeListener('end', onend); 751cb0ef41Sopenharmony_ci source.removeListener('close', onclose); 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci source.removeListener('error', onerror); 781cb0ef41Sopenharmony_ci dest.removeListener('error', onerror); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci source.removeListener('end', cleanup); 811cb0ef41Sopenharmony_ci source.removeListener('close', cleanup); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci dest.removeListener('close', cleanup); 841cb0ef41Sopenharmony_ci } 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci source.on('end', cleanup); 871cb0ef41Sopenharmony_ci source.on('close', cleanup); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci dest.on('close', cleanup); 901cb0ef41Sopenharmony_ci dest.emit('pipe', source); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci // Allow for unix-like usage: A.pipe(B).pipe(C) 931cb0ef41Sopenharmony_ci return dest; 941cb0ef41Sopenharmony_ci}; 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_cifunction prependListener(emitter, event, fn) { 971cb0ef41Sopenharmony_ci // Sadly this is not cacheable as some libraries bundle their own 981cb0ef41Sopenharmony_ci // event emitter implementation with them. 991cb0ef41Sopenharmony_ci if (typeof emitter.prependListener === 'function') 1001cb0ef41Sopenharmony_ci return emitter.prependListener(event, fn); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci // This is a hack to make sure that our error handler is attached before any 1031cb0ef41Sopenharmony_ci // userland ones. NEVER DO THIS. This is here only because this code needs 1041cb0ef41Sopenharmony_ci // to continue to work with older versions of Node.js that do not include 1051cb0ef41Sopenharmony_ci // the prependListener() method. The goal is to eventually remove this hack. 1061cb0ef41Sopenharmony_ci if (!emitter._events || !emitter._events[event]) 1071cb0ef41Sopenharmony_ci emitter.on(event, fn); 1081cb0ef41Sopenharmony_ci else if (ArrayIsArray(emitter._events[event])) 1091cb0ef41Sopenharmony_ci emitter._events[event].unshift(fn); 1101cb0ef41Sopenharmony_ci else 1111cb0ef41Sopenharmony_ci emitter._events[event] = [fn, emitter._events[event]]; 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_cimodule.exports = { Stream, prependListener }; 115