Skip to content

Commit 5edbe1a

Browse files
committed
stream: simpler stream constructon
Via revealing constructor pattern. Referenced to discussion in issue nodejs/readable-stream#102 of iojs/readable-stream
1 parent 3e67d7e commit 5edbe1a

7 files changed

+245
-2
lines changed

doc/api/stream.markdown

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ of stream class you are writing:
718718
<p>[Writable](#stream_class_stream_writable_1)</p>
719719
</td>
720720
<td>
721-
<p><code>[_write][]</code></p>
721+
<p><code>[_write][]</code>, <code>_writev</code></p>
722722
</td>
723723
</tr>
724724
<tr>
@@ -729,7 +729,7 @@ of stream class you are writing:
729729
<p>[Duplex](#stream_class_stream_duplex_1)</p>
730730
</td>
731731
<td>
732-
<p><code>[_read][]</code>, <code>[_write][]</code></p>
732+
<p><code>[_read][]</code>, <code>[_write][]</code>, <code>_writev</code></p>
733733
</td>
734734
</tr>
735735
<tr>
@@ -1315,6 +1315,135 @@ for examples and testing, but there are occasionally use cases where
13151315
it can come in handy as a building block for novel sorts of streams.
13161316

13171317

1318+
## Simplified API Via Revealing Constructor Pattern
1319+
1320+
<!--type=misc-->
1321+
1322+
To implement any sort of stream you can now pass that streams specific methods as parameters to the constructors options:
1323+
1324+
<table>
1325+
<thead>
1326+
<tr>
1327+
<th>
1328+
<p>Use-case</p>
1329+
</th>
1330+
<th>
1331+
<p>Class</p>
1332+
</th>
1333+
<th>
1334+
<p>Method(s) to implement</p>
1335+
</th>
1336+
</tr>
1337+
</thead>
1338+
<tr>
1339+
<td>
1340+
<p>Reading only</p>
1341+
</td>
1342+
<td>
1343+
<p>[Readable](#stream_class_stream_readable_1)</p>
1344+
</td>
1345+
<td>
1346+
<p><code>[read][_read]</code></p>
1347+
</td>
1348+
</tr>
1349+
<tr>
1350+
<td>
1351+
<p>Writing only</p>
1352+
</td>
1353+
<td>
1354+
<p>[Writable](#stream_class_stream_writable_1)</p>
1355+
</td>
1356+
<td>
1357+
<p><code>[write][_write]</code></p>
1358+
</td>
1359+
</tr>
1360+
<tr>
1361+
<td>
1362+
<p>Reading and writing</p>
1363+
</td>
1364+
<td>
1365+
<p>[Duplex](#stream_class_stream_duplex_1)</p>
1366+
</td>
1367+
<td>
1368+
<p><code>[read][_read]</code>, <code>[write][_write]</code>, <code>writev</code></p>
1369+
</td>
1370+
</tr>
1371+
<tr>
1372+
<td>
1373+
<p>Operate on written data, then read the result</p>
1374+
</td>
1375+
<td>
1376+
<p>[Transform](#stream_class_stream_transform_1)</p>
1377+
</td>
1378+
<td>
1379+
<p><code>transform</code>, <code>flush</code></p>
1380+
</td>
1381+
</tr>
1382+
</table>
1383+
1384+
Examples:
1385+
1386+
### Readable
1387+
```javascript
1388+
var readable = new stream.Readable({
1389+
read: function(n) {
1390+
// sets this._read under the hood
1391+
}
1392+
});
1393+
```
1394+
1395+
### Writable
1396+
```javascript
1397+
var writable = new stream.Writable({
1398+
write: function(chunk, encoding, next) {
1399+
// sets this._write under the hood
1400+
}
1401+
});
1402+
1403+
// or
1404+
1405+
var writable = new stream.Writable({
1406+
writev: function(chunks, next) {
1407+
// sets this._writev under the hood
1408+
}
1409+
});
1410+
```
1411+
1412+
### Duplex
1413+
```javascript
1414+
var duplex = new stream.Duplex({
1415+
read: function(n) {
1416+
// sets this._read under the hood
1417+
},
1418+
write: function(chunk, encoding, next) {
1419+
// sets this._write under the hood
1420+
}
1421+
});
1422+
1423+
// or
1424+
1425+
var duplex = new stream.Duplex({
1426+
read: function(n) {
1427+
// sets this._read under the hood
1428+
},
1429+
writev: function(chunks, next) {
1430+
// sets this._writev under the hood
1431+
}
1432+
});
1433+
```
1434+
1435+
### Transform
1436+
```javascript
1437+
var transform = new stream.Transform({
1438+
transform: function(chunk, encoding, next) {
1439+
// sets this._transform under the hood
1440+
},
1441+
flush: function(done) {
1442+
// sets this._flush under the hood
1443+
}
1444+
});
1445+
```
1446+
13181447
## Streams: Under the Hood
13191448

13201449
<!--type=misc-->

lib/_stream_readable.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ function Readable(options) {
8585
// legacy
8686
this.readable = true;
8787

88+
if (options && typeof options.read === 'function')
89+
this._read = options.read;
90+
8891
Stream.call(this);
8992
}
9093

lib/_stream_transform.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ function Transform(options) {
105105
// sync guard flag.
106106
this._readableState.sync = false;
107107

108+
if (options) {
109+
if (typeof options.transform === 'function')
110+
this._transform = options.transform;
111+
112+
if (typeof options.flush === 'function')
113+
this._flush = options.flush;
114+
}
115+
108116
this.once('prefinish', function() {
109117
if (typeof this._flush === 'function')
110118
this._flush(function(er) {

lib/_stream_writable.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ function Writable(options) {
137137
// legacy.
138138
this.writable = true;
139139

140+
if (options) {
141+
if (typeof options.write === 'function')
142+
this._write = options.write;
143+
144+
if (typeof options.writev === 'function')
145+
this._writev = options.writev;
146+
}
147+
140148
Stream.call(this);
141149
}
142150

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
4+
var Readable = require('stream').Readable;
5+
6+
var _readCalled = false;
7+
function _read(n) {
8+
_readCalled = true;
9+
this.push(null);
10+
}
11+
12+
var r = new Readable({ read: _read });
13+
r.resume();
14+
15+
process.on('exit', function () {
16+
assert.equal(r._read, _read);
17+
assert(_readCalled);
18+
console.log('ok');
19+
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
4+
var Transform = require('stream').Transform;
5+
6+
var _transformCalled = false;
7+
function _transform(d, e, n) {
8+
_transformCalled = true;
9+
n();
10+
}
11+
12+
var _flushCalled = false;
13+
function _flush(n) {
14+
_flushCalled = true;
15+
n();
16+
}
17+
18+
var t = new Transform({
19+
transform: _transform,
20+
flush: _flush
21+
});
22+
23+
t.end(new Buffer('blerg'));
24+
t.resume();
25+
26+
process.on('exit', function () {
27+
assert.equal(t._transform, _transform);
28+
assert.equal(t._flush, _flush);
29+
assert(_transformCalled);
30+
assert(_flushCalled);
31+
console.log('ok');
32+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
4+
var Writable = require('stream').Writable;
5+
6+
(function one() {
7+
var _writeCalled = false;
8+
function _write(d, e, n) {
9+
_writeCalled = true;
10+
}
11+
12+
var w = new Writable({ write: _write });
13+
w.end(new Buffer('blerg'));
14+
15+
process.on('exit', function () {
16+
assert.equal(w._write, _write);
17+
assert(_writeCalled);
18+
console.log('ok 1');
19+
});
20+
}());
21+
22+
(function two() {
23+
var _writevCalled = false;
24+
var dLength = 0;
25+
26+
function _writev(d, n) {
27+
dLength = d.length;
28+
_writevCalled = true;
29+
}
30+
31+
var w = new Writable({ writev: _writev });
32+
w.cork();
33+
34+
w.write(new Buffer('blerg'));
35+
w.write(new Buffer('blerg'));
36+
w.end();
37+
38+
process.on('exit', function () {
39+
assert.equal(w._writev, _writev);
40+
assert.equal(dLength, 2);
41+
assert(_writevCalled);
42+
console.log('ok 2');
43+
});
44+
}());

0 commit comments

Comments
 (0)