forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathduplexpair.js
62 lines (53 loc) · 1.34 KB
/
duplexpair.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
'use strict';
const {
Symbol,
} = primordials;
const { Duplex } = require('stream');
const assert = require('internal/assert');
const kCallback = Symbol('Callback');
const kInitOtherSide = Symbol('InitOtherSide');
class DuplexSide extends Duplex {
#otherSide = null;
constructor(options) {
super(options);
this[kCallback] = null;
this.#otherSide = null;
}
[kInitOtherSide](otherSide) {
// Ensure this can only be set once, to enforce encapsulation.
if (this.#otherSide === null) {
this.#otherSide = otherSide;
} else {
assert(this.#otherSide === null);
}
}
_read() {
const callback = this[kCallback];
if (callback) {
this[kCallback] = null;
callback();
}
}
_write(chunk, encoding, callback) {
assert(this.#otherSide !== null);
assert(this.#otherSide[kCallback] === null);
if (chunk.length === 0) {
process.nextTick(callback);
} else {
this.#otherSide.push(chunk);
this.#otherSide[kCallback] = callback;
}
}
_final(callback) {
this.#otherSide.on('end', callback);
this.#otherSide.push(null);
}
}
function duplexPair(options) {
const side0 = new DuplexSide(options);
const side1 = new DuplexSide(options);
side0[kInitOtherSide](side1);
side1[kInitOtherSide](side0);
return [ side0, side1 ];
}
module.exports = duplexPair;