Skip to content

Commit a01c02d

Browse files
lpincaMayaLekova
authored andcommitted
stream: augment BufferList.prototype
Move functions that deal with `BufferList` to `BufferList.prototype`. PR-URL: nodejs#18353 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 039d81f commit a01c02d

File tree

2 files changed

+87
-90
lines changed

2 files changed

+87
-90
lines changed

lib/_stream_readable.js

+2-90
Original file line numberDiff line numberDiff line change
@@ -987,106 +987,18 @@ function fromList(n, state) {
987987
if (state.decoder)
988988
ret = state.buffer.join('');
989989
else if (state.buffer.length === 1)
990-
ret = state.buffer.head.data;
990+
ret = state.buffer.first();
991991
else
992992
ret = state.buffer.concat(state.length);
993993
state.buffer.clear();
994994
} else {
995995
// read part of list
996-
ret = fromListPartial(n, state.buffer, state.decoder);
996+
ret = state.buffer.consume(n, state.decoder);
997997
}
998998

999999
return ret;
10001000
}
10011001

1002-
// Extracts only enough buffered data to satisfy the amount requested.
1003-
// This function is designed to be inlinable, so please take care when making
1004-
// changes to the function body.
1005-
function fromListPartial(n, list, hasStrings) {
1006-
var ret;
1007-
if (n < list.head.data.length) {
1008-
// slice is the same for buffers and strings
1009-
ret = list.head.data.slice(0, n);
1010-
list.head.data = list.head.data.slice(n);
1011-
} else if (n === list.head.data.length) {
1012-
// first chunk is a perfect match
1013-
ret = list.shift();
1014-
} else {
1015-
// result spans more than one buffer
1016-
ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
1017-
}
1018-
return ret;
1019-
}
1020-
1021-
// Copies a specified amount of characters from the list of buffered data
1022-
// chunks.
1023-
// This function is designed to be inlinable, so please take care when making
1024-
// changes to the function body.
1025-
function copyFromBufferString(n, list) {
1026-
var p = list.head;
1027-
var c = 1;
1028-
var ret = p.data;
1029-
n -= ret.length;
1030-
while (p = p.next) {
1031-
const str = p.data;
1032-
const nb = (n > str.length ? str.length : n);
1033-
if (nb === str.length)
1034-
ret += str;
1035-
else
1036-
ret += str.slice(0, n);
1037-
n -= nb;
1038-
if (n === 0) {
1039-
if (nb === str.length) {
1040-
++c;
1041-
if (p.next)
1042-
list.head = p.next;
1043-
else
1044-
list.head = list.tail = null;
1045-
} else {
1046-
list.head = p;
1047-
p.data = str.slice(nb);
1048-
}
1049-
break;
1050-
}
1051-
++c;
1052-
}
1053-
list.length -= c;
1054-
return ret;
1055-
}
1056-
1057-
// Copies a specified amount of bytes from the list of buffered data chunks.
1058-
// This function is designed to be inlinable, so please take care when making
1059-
// changes to the function body.
1060-
function copyFromBuffer(n, list) {
1061-
const ret = Buffer.allocUnsafe(n);
1062-
var p = list.head;
1063-
var c = 1;
1064-
p.data.copy(ret);
1065-
n -= p.data.length;
1066-
while (p = p.next) {
1067-
const buf = p.data;
1068-
const nb = (n > buf.length ? buf.length : n);
1069-
buf.copy(ret, ret.length - n, 0, nb);
1070-
n -= nb;
1071-
if (n === 0) {
1072-
if (nb === buf.length) {
1073-
++c;
1074-
if (p.next)
1075-
list.head = p.next;
1076-
else
1077-
list.head = list.tail = null;
1078-
} else {
1079-
list.head = p;
1080-
p.data = buf.slice(nb);
1081-
}
1082-
break;
1083-
}
1084-
++c;
1085-
}
1086-
list.length -= c;
1087-
return ret;
1088-
}
1089-
10901002
function endReadable(stream) {
10911003
var state = stream._readableState;
10921004

lib/internal/streams/BufferList.js

+85
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,91 @@ module.exports = class BufferList {
7373
return ret;
7474
}
7575

76+
// Consumes a specified amount of bytes or characters from the buffered data.
77+
consume(n, hasStrings) {
78+
var ret;
79+
if (n < this.head.data.length) {
80+
// `slice` is the same for buffers and strings.
81+
ret = this.head.data.slice(0, n);
82+
this.head.data = this.head.data.slice(n);
83+
} else if (n === this.head.data.length) {
84+
// First chunk is a perfect match.
85+
ret = this.shift();
86+
} else {
87+
// Result spans more than one buffer.
88+
ret = hasStrings ? this._getString(n) : this._getBuffer(n);
89+
}
90+
return ret;
91+
}
92+
93+
first() {
94+
return this.head.data;
95+
}
96+
97+
// Consumes a specified amount of characters from the buffered data.
98+
_getString(n) {
99+
var p = this.head;
100+
var c = 1;
101+
var ret = p.data;
102+
n -= ret.length;
103+
while (p = p.next) {
104+
const str = p.data;
105+
const nb = (n > str.length ? str.length : n);
106+
if (nb === str.length)
107+
ret += str;
108+
else
109+
ret += str.slice(0, n);
110+
n -= nb;
111+
if (n === 0) {
112+
if (nb === str.length) {
113+
++c;
114+
if (p.next)
115+
this.head = p.next;
116+
else
117+
this.head = this.tail = null;
118+
} else {
119+
this.head = p;
120+
p.data = str.slice(nb);
121+
}
122+
break;
123+
}
124+
++c;
125+
}
126+
this.length -= c;
127+
return ret;
128+
}
129+
130+
// Consumes a specified amount of bytes from the buffered data.
131+
_getBuffer(n) {
132+
const ret = Buffer.allocUnsafe(n);
133+
var p = this.head;
134+
var c = 1;
135+
p.data.copy(ret);
136+
n -= p.data.length;
137+
while (p = p.next) {
138+
const buf = p.data;
139+
const nb = (n > buf.length ? buf.length : n);
140+
buf.copy(ret, ret.length - n, 0, nb);
141+
n -= nb;
142+
if (n === 0) {
143+
if (nb === buf.length) {
144+
++c;
145+
if (p.next)
146+
this.head = p.next;
147+
else
148+
this.head = this.tail = null;
149+
} else {
150+
this.head = p;
151+
p.data = buf.slice(nb);
152+
}
153+
break;
154+
}
155+
++c;
156+
}
157+
this.length -= c;
158+
return ret;
159+
}
160+
76161
[inspect.custom]() {
77162
const obj = inspect({ length: this.length });
78163
return `${this.constructor.name} ${obj}`;

0 commit comments

Comments
 (0)