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