1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
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/lib/_stream_readable.js');
|
29 | Stream.Writable = require('readable-stream/lib/_stream_writable.js');
|
30 | Stream.Duplex = require('readable-stream/lib/_stream_duplex.js');
|
31 | Stream.Transform = require('readable-stream/lib/_stream_transform.js');
|
32 | Stream.PassThrough = require('readable-stream/lib/_stream_passthrough.js');
|
33 | Stream.finished = require('readable-stream/lib/internal/streams/end-of-stream.js')
|
34 | Stream.pipeline = require('readable-stream/lib/internal/streams/pipeline.js')
|
35 |
|
36 |
|
37 | Stream.Stream = Stream;
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | function Stream() {
|
45 | EE.call(this);
|
46 | }
|
47 |
|
48 | Stream.prototype.pipe = function(dest, options) {
|
49 | var source = this;
|
50 |
|
51 | function ondata(chunk) {
|
52 | if (dest.writable) {
|
53 | if (false === dest.write(chunk) && source.pause) {
|
54 | source.pause();
|
55 | }
|
56 | }
|
57 | }
|
58 |
|
59 | source.on('data', ondata);
|
60 |
|
61 | function ondrain() {
|
62 | if (source.readable && source.resume) {
|
63 | source.resume();
|
64 | }
|
65 | }
|
66 |
|
67 | dest.on('drain', ondrain);
|
68 |
|
69 |
|
70 |
|
71 | if (!dest._isStdio && (!options || options.end !== false)) {
|
72 | source.on('end', onend);
|
73 | source.on('close', onclose);
|
74 | }
|
75 |
|
76 | var didOnEnd = false;
|
77 | function onend() {
|
78 | if (didOnEnd) return;
|
79 | didOnEnd = true;
|
80 |
|
81 | dest.end();
|
82 | }
|
83 |
|
84 |
|
85 | function onclose() {
|
86 | if (didOnEnd) return;
|
87 | didOnEnd = true;
|
88 |
|
89 | if (typeof dest.destroy === 'function') dest.destroy();
|
90 | }
|
91 |
|
92 |
|
93 | function onerror(er) {
|
94 | cleanup();
|
95 | if (EE.listenerCount(this, 'error') === 0) {
|
96 | throw er;
|
97 | }
|
98 | }
|
99 |
|
100 | source.on('error', onerror);
|
101 | dest.on('error', onerror);
|
102 |
|
103 |
|
104 | function cleanup() {
|
105 | source.removeListener('data', ondata);
|
106 | dest.removeListener('drain', ondrain);
|
107 |
|
108 | source.removeListener('end', onend);
|
109 | source.removeListener('close', onclose);
|
110 |
|
111 | source.removeListener('error', onerror);
|
112 | dest.removeListener('error', onerror);
|
113 |
|
114 | source.removeListener('end', cleanup);
|
115 | source.removeListener('close', cleanup);
|
116 |
|
117 | dest.removeListener('close', cleanup);
|
118 | }
|
119 |
|
120 | source.on('end', cleanup);
|
121 | source.on('close', cleanup);
|
122 |
|
123 | dest.on('close', cleanup);
|
124 |
|
125 | dest.emit('pipe', source);
|
126 |
|
127 |
|
128 | return dest;
|
129 | };
|