Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 67e1819

Browse filesBrowse files
umamialextrevnorris
authored andcommitted
buffer: add includes() for parity with TypedArray
Add Buffer#includes() by wrapping an indexOf and performing a strict equals check to -1. The includes method takes the search value, byteOffset, and encoding as arguments. The test is a modified version of the indexOf test. Fixes: #3552 PR-URL: #3567 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 23e7703 commit 67e1819
Copy full SHA for 67e1819

File tree

Expand file treeCollapse file tree

3 files changed

+274
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+274
-0
lines changed
Open diff view settings
Collapse file

‎doc/api/buffer.markdown‎

Copy file name to clipboardExpand all lines: doc/api/buffer.markdown
+13Lines changed: 13 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,19 @@ Strings are interpreted as UTF8. Buffers will use the entire buffer. So in order
291291
to compare a partial Buffer use [`Buffer#slice()`][]. Numbers can range from 0 to
292292
255.
293293

294+
### buf.includes(value[, byteOffset][, encoding])
295+
296+
* `value` String, Buffer or Number
297+
* `byteOffset` Number, Optional, Default: 0
298+
* `encoding` String, Optional, Default: 'utf8'
299+
300+
Operates similar to
301+
[Array#includes()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes).
302+
Accepts a String, Buffer or Number. Strings are interpreted as UTF8 unless
303+
overridden with the `encoding` argument. Buffers will use the entire buffer.
304+
So in order to compare a partial Buffer use `Buffer#slice()`. Numbers can range
305+
from 0 to 255.
306+
294307
### buf.length
295308

296309
* Number
Collapse file

‎lib/buffer.js‎

Copy file name to clipboardExpand all lines: lib/buffer.js
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,11 @@ Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
488488
};
489489

490490

491+
Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
492+
return this.indexOf(val, byteOffset, encoding) !== -1;
493+
};
494+
495+
491496
Buffer.prototype.fill = function fill(val, start, end) {
492497
start = start >> 0;
493498
end = (end === undefined) ? this.length : end >> 0;
Collapse file
+256Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
5+
const Buffer = require('buffer').Buffer;
6+
7+
const b = new Buffer('abcdef');
8+
const buf_a = new Buffer('a');
9+
const buf_bc = new Buffer('bc');
10+
const buf_f = new Buffer('f');
11+
const buf_z = new Buffer('z');
12+
const buf_empty = new Buffer('');
13+
14+
assert(b.includes('a'));
15+
assert(!b.includes('a', 1));
16+
assert(!b.includes('a', -1));
17+
assert(!b.includes('a', -4));
18+
assert(b.includes('a', -b.length));
19+
assert(b.includes('a', NaN));
20+
assert(b.includes('a', -Infinity));
21+
assert(!b.includes('a', Infinity));
22+
assert(b.includes('bc'));
23+
assert(!b.includes('bc', 2));
24+
assert(!b.includes('bc', -1));
25+
assert(!b.includes('bc', -3));
26+
assert(b.includes('bc', -5));
27+
assert(b.includes('bc', NaN));
28+
assert(b.includes('bc', -Infinity));
29+
assert(!b.includes('bc', Infinity));
30+
assert(b.includes('f'), b.length - 1);
31+
assert(!b.includes('z'));
32+
assert(!b.includes(''));
33+
assert(!b.includes('', 1));
34+
assert(!b.includes('', b.length + 1));
35+
assert(!b.includes('', Infinity));
36+
assert(b.includes(buf_a));
37+
assert(!b.includes(buf_a, 1));
38+
assert(!b.includes(buf_a, -1));
39+
assert(!b.includes(buf_a, -4));
40+
assert(b.includes(buf_a, -b.length));
41+
assert(b.includes(buf_a, NaN));
42+
assert(b.includes(buf_a, -Infinity));
43+
assert(!b.includes(buf_a, Infinity));
44+
assert(b.includes(buf_bc));
45+
assert(!b.includes(buf_bc, 2));
46+
assert(!b.includes(buf_bc, -1));
47+
assert(!b.includes(buf_bc, -3));
48+
assert(b.includes(buf_bc, -5));
49+
assert(b.includes(buf_bc, NaN));
50+
assert(b.includes(buf_bc, -Infinity));
51+
assert(!b.includes(buf_bc, Infinity));
52+
assert(b.includes(buf_f), b.length - 1);
53+
assert(!b.includes(buf_z));
54+
assert(!b.includes(buf_empty));
55+
assert(!b.includes(buf_empty, 1));
56+
assert(!b.includes(buf_empty, b.length + 1));
57+
assert(!b.includes(buf_empty, Infinity));
58+
assert(b.includes(0x61));
59+
assert(!b.includes(0x61, 1));
60+
assert(!b.includes(0x61, -1));
61+
assert(!b.includes(0x61, -4));
62+
assert(b.includes(0x61, -b.length));
63+
assert(b.includes(0x61, NaN));
64+
assert(b.includes(0x61, -Infinity));
65+
assert(!b.includes(0x61, Infinity));
66+
assert(!b.includes(0x0));
67+
68+
// test offsets
69+
assert(b.includes('d', 2));
70+
assert(b.includes('f', 5));
71+
assert(b.includes('f', -1));
72+
assert(!b.includes('f', 6));
73+
74+
assert(b.includes(Buffer('d'), 2));
75+
assert(b.includes(Buffer('f'), 5));
76+
assert(b.includes(Buffer('f'), -1));
77+
assert(!b.includes(Buffer('f'), 6));
78+
79+
assert(!Buffer('ff').includes(Buffer('f'), 1, 'ucs2'));
80+
81+
// test hex encoding
82+
assert(
83+
Buffer(b.toString('hex'), 'hex')
84+
.includes('64', 0, 'hex'));
85+
assert(
86+
Buffer(b.toString('hex'), 'hex')
87+
.includes(Buffer('64', 'hex'), 0, 'hex'));
88+
89+
// test base64 encoding
90+
assert(
91+
Buffer(b.toString('base64'), 'base64')
92+
.includes('ZA==', 0, 'base64'));
93+
assert(
94+
Buffer(b.toString('base64'), 'base64')
95+
.includes(Buffer('ZA==', 'base64'), 0, 'base64'));
96+
97+
// test ascii encoding
98+
assert(
99+
Buffer(b.toString('ascii'), 'ascii')
100+
.includes('d', 0, 'ascii'));
101+
assert(
102+
Buffer(b.toString('ascii'), 'ascii')
103+
.includes(Buffer('d', 'ascii'), 0, 'ascii'));
104+
105+
// test binary encoding
106+
assert(
107+
Buffer(b.toString('binary'), 'binary')
108+
.includes('d', 0, 'binary'));
109+
assert(
110+
Buffer(b.toString('binary'), 'binary')
111+
.includes(Buffer('d', 'binary'), 0, 'binary'));
112+
113+
114+
// test usc2 encoding
115+
var twoByteString = new Buffer('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
116+
117+
assert(twoByteString.includes('\u0395', 4, 'ucs2'));
118+
assert(twoByteString.includes('\u03a3', -4, 'ucs2'));
119+
assert(twoByteString.includes('\u03a3', -6, 'ucs2'));
120+
assert(twoByteString.includes(
121+
new Buffer('\u03a3', 'ucs2'), -6, 'ucs2'));
122+
assert(!twoByteString.includes('\u03a3', -2, 'ucs2'));
123+
124+
const mixedByteStringUcs2 =
125+
new Buffer('\u039a\u0391abc\u03a3\u03a3\u0395', 'ucs2');
126+
assert(mixedByteStringUcs2.includes('bc', 0, 'ucs2'));
127+
assert(mixedByteStringUcs2.includes('\u03a3', 0, 'ucs2'));
128+
assert(!mixedByteStringUcs2.includes('\u0396', 0, 'ucs2'));
129+
130+
assert(
131+
6, mixedByteStringUcs2.includes(new Buffer('bc', 'ucs2'), 0, 'ucs2'));
132+
assert(
133+
10, mixedByteStringUcs2.includes(new Buffer('\u03a3', 'ucs2'), 0, 'ucs2'));
134+
assert(
135+
-1, mixedByteStringUcs2.includes(new Buffer('\u0396', 'ucs2'), 0, 'ucs2'));
136+
137+
twoByteString = new Buffer('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
138+
139+
// Test single char pattern
140+
assert(twoByteString.includes('\u039a', 0, 'ucs2'));
141+
assert(twoByteString.includes('\u0391', 0, 'ucs2'), 'Alpha');
142+
assert(twoByteString.includes('\u03a3', 0, 'ucs2'), 'First Sigma');
143+
assert(twoByteString.includes('\u03a3', 6, 'ucs2'), 'Second Sigma');
144+
assert(twoByteString.includes('\u0395', 0, 'ucs2'), 'Epsilon');
145+
assert(!twoByteString.includes('\u0392', 0, 'ucs2'), 'Not beta');
146+
147+
// Test multi-char pattern
148+
assert(twoByteString.includes('\u039a\u0391', 0, 'ucs2'), 'Lambda Alpha');
149+
assert(twoByteString.includes('\u0391\u03a3', 0, 'ucs2'), 'Alpha Sigma');
150+
assert(twoByteString.includes('\u03a3\u03a3', 0, 'ucs2'), 'Sigma Sigma');
151+
assert(twoByteString.includes('\u03a3\u0395', 0, 'ucs2'), 'Sigma Epsilon');
152+
153+
const mixedByteStringUtf8 = new Buffer('\u039a\u0391abc\u03a3\u03a3\u0395');
154+
assert(mixedByteStringUtf8.includes('bc'));
155+
assert(mixedByteStringUtf8.includes('bc', 5));
156+
assert(mixedByteStringUtf8.includes('bc', -8));
157+
assert(mixedByteStringUtf8.includes('\u03a3'));
158+
assert(!mixedByteStringUtf8.includes('\u0396'));
159+
160+
161+
// Test complex string includes algorithms. Only trigger for long strings.
162+
// Long string that isn't a simple repeat of a shorter string.
163+
var longString = 'A';
164+
for (var i = 66; i < 76; i++) { // from 'B' to 'K'
165+
longString = longString + String.fromCharCode(i) + longString;
166+
}
167+
168+
const longBufferString = new Buffer(longString);
169+
170+
// pattern of 15 chars, repeated every 16 chars in long
171+
var pattern = 'ABACABADABACABA';
172+
for (var i = 0; i < longBufferString.length - pattern.length; i += 7) {
173+
const includes = longBufferString.includes(pattern, i);
174+
assert(includes, 'Long ABACABA...-string at index ' + i);
175+
}
176+
assert(longBufferString.includes('AJABACA'), 'Long AJABACA, First J');
177+
assert(longBufferString.includes('AJABACA', 511), 'Long AJABACA, Second J');
178+
179+
pattern = 'JABACABADABACABA';
180+
assert(longBufferString.includes(pattern), 'Long JABACABA..., First J');
181+
assert(longBufferString.includes(pattern, 512), 'Long JABACABA..., Second J');
182+
183+
// Search for a non-ASCII string in a pure ASCII string.
184+
const asciiString = new Buffer(
185+
'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf');
186+
assert(!asciiString.includes('\x2061'));
187+
assert(asciiString.includes('leb', 0));
188+
189+
// Search in string containing many non-ASCII chars.
190+
const allCodePoints = [];
191+
for (var i = 0; i < 65536; i++) allCodePoints[i] = i;
192+
const allCharsString = String.fromCharCode.apply(String, allCodePoints);
193+
const allCharsBufferUtf8 = new Buffer(allCharsString);
194+
const allCharsBufferUcs2 = new Buffer(allCharsString, 'ucs2');
195+
196+
// Search for string long enough to trigger complex search with ASCII pattern
197+
// and UC16 subject.
198+
assert(!allCharsBufferUtf8.includes('notfound'));
199+
assert(!allCharsBufferUcs2.includes('notfound'));
200+
201+
// Find substrings in Utf8.
202+
var lengths = [1, 3, 15]; // Single char, simple and complex.
203+
var indices = [0x5, 0x60, 0x400, 0x680, 0x7ee, 0xFF02, 0x16610, 0x2f77b];
204+
for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
205+
for (var i = 0; i < indices.length; i++) {
206+
const index = indices[i];
207+
var length = lengths[lengthIndex];
208+
209+
if (index + length > 0x7F) {
210+
length = 2 * length;
211+
}
212+
213+
if (index + length > 0x7FF) {
214+
length = 3 * length;
215+
}
216+
217+
if (index + length > 0xFFFF) {
218+
length = 4 * length;
219+
}
220+
221+
const patternBufferUtf8 = allCharsBufferUtf8.slice(index, index + length);
222+
assert(index, allCharsBufferUtf8.includes(patternBufferUtf8));
223+
224+
const patternStringUtf8 = patternBufferUtf8.toString();
225+
assert(index, allCharsBufferUtf8.includes(patternStringUtf8));
226+
}
227+
}
228+
229+
// Find substrings in Usc2.
230+
lengths = [2, 4, 16]; // Single char, simple and complex.
231+
indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0];
232+
for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
233+
for (var i = 0; i < indices.length; i++) {
234+
const index = indices[i] * 2;
235+
var length = lengths[lengthIndex];
236+
237+
const patternBufferUcs2 =
238+
allCharsBufferUcs2.slice(index, index + length);
239+
assert(
240+
index, allCharsBufferUcs2.includes(patternBufferUcs2, 0, 'ucs2'));
241+
242+
const patternStringUcs2 = patternBufferUcs2.toString('ucs2');
243+
assert(
244+
index, allCharsBufferUcs2.includes(patternStringUcs2, 0, 'ucs2'));
245+
}
246+
}
247+
248+
assert.throws(function() {
249+
b.includes(function() { });
250+
});
251+
assert.throws(function() {
252+
b.includes({});
253+
});
254+
assert.throws(function() {
255+
b.includes([]);
256+
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.