Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80522 views
1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// "Software"), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
module.exports = Stream;
23
24
var EE = require('events').EventEmitter;
25
var inherits = require('inherits');
26
27
inherits(Stream, EE);
28
Stream.Readable = require('readable-stream/readable.js');
29
Stream.Writable = require('readable-stream/writable.js');
30
Stream.Duplex = require('readable-stream/duplex.js');
31
Stream.Transform = require('readable-stream/transform.js');
32
Stream.PassThrough = require('readable-stream/passthrough.js');
33
34
// Backwards-compat with node 0.4.x
35
Stream.Stream = Stream;
36
37
38
39
// old-style streams. Note that the pipe method (the only relevant
40
// part of this class) is overridden in the Readable class.
41
42
function Stream() {
43
EE.call(this);
44
}
45
46
Stream.prototype.pipe = function(dest, options) {
47
var source = this;
48
49
function ondata(chunk) {
50
if (dest.writable) {
51
if (false === dest.write(chunk) && source.pause) {
52
source.pause();
53
}
54
}
55
}
56
57
source.on('data', ondata);
58
59
function ondrain() {
60
if (source.readable && source.resume) {
61
source.resume();
62
}
63
}
64
65
dest.on('drain', ondrain);
66
67
// If the 'end' option is not supplied, dest.end() will be called when
68
// source gets the 'end' or 'close' events. Only dest.end() once.
69
if (!dest._isStdio && (!options || options.end !== false)) {
70
source.on('end', onend);
71
source.on('close', onclose);
72
}
73
74
var didOnEnd = false;
75
function onend() {
76
if (didOnEnd) return;
77
didOnEnd = true;
78
79
dest.end();
80
}
81
82
83
function onclose() {
84
if (didOnEnd) return;
85
didOnEnd = true;
86
87
if (typeof dest.destroy === 'function') dest.destroy();
88
}
89
90
// don't leave dangling pipes when there are errors.
91
function onerror(er) {
92
cleanup();
93
if (EE.listenerCount(this, 'error') === 0) {
94
throw er; // Unhandled stream error in pipe.
95
}
96
}
97
98
source.on('error', onerror);
99
dest.on('error', onerror);
100
101
// remove all the event listeners that were added.
102
function cleanup() {
103
source.removeListener('data', ondata);
104
dest.removeListener('drain', ondrain);
105
106
source.removeListener('end', onend);
107
source.removeListener('close', onclose);
108
109
source.removeListener('error', onerror);
110
dest.removeListener('error', onerror);
111
112
source.removeListener('end', cleanup);
113
source.removeListener('close', cleanup);
114
115
dest.removeListener('close', cleanup);
116
}
117
118
source.on('end', cleanup);
119
source.on('close', cleanup);
120
121
dest.on('close', cleanup);
122
123
dest.emit('pipe', source);
124
125
// Allow for unix-like usage: A.pipe(B).pipe(C)
126
return dest;
127
};
128
129