Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions doc/api/buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -2069,11 +2069,14 @@ console.log(buf.fill('zz', 'hex'));
// Throws an exception.
```

### `buf.includes(value[, byteOffset][, encoding])`
### `buf.includes(value[, start[, end]][, encoding])`

<!-- YAML
added: v5.3.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62390
description: Added the `end` parameter.
- version:
- v25.5.0
- v24.13.1
Expand All @@ -2082,8 +2085,10 @@ changes:
-->

* `value` {string|Buffer|Uint8Array|integer} What to search for.
* `byteOffset` {integer} Where to begin searching in `buf`. If negative, then
* `start` {integer} Where to begin searching in `buf`. If negative, then
offset is calculated from the end of `buf`. **Default:** `0`.
* `end` {integer} Where to stop searching in `buf` (exclusive). **Default:**
`buf.length`.
* `encoding` {string} If `value` is a string, this is its encoding.
**Default:** `'utf8'`.
* Returns: {boolean} `true` if `value` was found in `buf`, `false` otherwise.
Expand Down Expand Up @@ -2132,11 +2137,14 @@ console.log(buf.includes('this', 4));
// Prints: false
```

### `buf.indexOf(value[, byteOffset][, encoding])`
### `buf.indexOf(value[, start[, end]][, encoding])`

<!-- YAML
added: v1.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62390
description: Added the `end` parameter.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/10236
description: The `value` can now be a `Uint8Array`.
Expand All @@ -2149,8 +2157,10 @@ changes:
-->

* `value` {string|Buffer|Uint8Array|integer} What to search for.
* `byteOffset` {integer} Where to begin searching in `buf`. If negative, then
* `start` {integer} Where to begin searching in `buf`. If negative, then
offset is calculated from the end of `buf`. **Default:** `0`.
* `end` {integer} Where to stop searching in `buf` (exclusive). **Default:**
`buf.length`.
* `encoding` {string} If `value` is a string, this is the encoding used to
determine the binary representation of the string that will be searched for in
`buf`. **Default:** `'utf8'`.
Expand Down Expand Up @@ -2310,20 +2320,25 @@ for (const key of buf.keys()) {
// 5
```

### `buf.lastIndexOf(value[, byteOffset][, encoding])`
### `buf.lastIndexOf(value[, start[, end]][, encoding])`

<!-- YAML
added: v6.0.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/62390
description: Added the `end` parameter.
- version: v8.0.0
pr-url: https://github.com/nodejs/node/pull/10236
description: The `value` can now be a `Uint8Array`.
-->

* `value` {string|Buffer|Uint8Array|integer} What to search for.
* `byteOffset` {integer} Where to begin searching in `buf`. If negative, then
* `start` {integer} Where to begin searching in `buf`. If negative, then
offset is calculated from the end of `buf`. **Default:**
`buf.length - 1`.
* `end` {integer} Where to stop searching in `buf` (exclusive). **Default:**
`buf.length`.
* `encoding` {string} If `value` is a string, this is the encoding used to
determine the binary representation of the string that will be searched for in
`buf`. **Default:** `'utf8'`.
Expand Down
79 changes: 53 additions & 26 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -700,83 +700,91 @@ const encodingOps = {
byteLength: byteLengthUtf8,
write: utf8Write,
slice: utf8Slice,
indexOf: (buf, val, byteOffset, dir) =>
indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir),
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir, end),
},
ucs2: {
encoding: 'ucs2',
encodingVal: encodingsMap.utf16le,
byteLength: (string) => string.length * 2,
write: ucs2Write,
slice: ucs2Slice,
indexOf: (buf, val, byteOffset, dir) =>
indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir),
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir, end),
},
utf16le: {
encoding: 'utf16le',
encodingVal: encodingsMap.utf16le,
byteLength: (string) => string.length * 2,
write: ucs2Write,
slice: ucs2Slice,
indexOf: (buf, val, byteOffset, dir) =>
indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir),
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir, end),
},
latin1: {
encoding: 'latin1',
encodingVal: encodingsMap.latin1,
byteLength: (string) => string.length,
write: latin1Write,
slice: latin1Slice,
indexOf: (buf, val, byteOffset, dir) =>
indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir),
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir, end),
},
ascii: {
encoding: 'ascii',
encodingVal: encodingsMap.ascii,
byteLength: (string) => string.length,
write: asciiWrite,
slice: asciiSlice,
indexOf: (buf, val, byteOffset, dir) =>
indexOfString(buf, val, byteOffset, encodingsMap.ascii, dir),
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfBuffer(buf,
fromStringFast(val, encodingOps.ascii),
byteOffset,
encodingsMap.ascii,
dir,
end),
},
base64: {
encoding: 'base64',
encodingVal: encodingsMap.base64,
byteLength: (string) => base64ByteLength(string, string.length),
write: base64Write,
slice: base64Slice,
indexOf: (buf, val, byteOffset, dir) =>
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfBuffer(buf,
fromStringFast(val, encodingOps.base64),
byteOffset,
encodingsMap.base64,
dir),
dir,
end),
},
base64url: {
encoding: 'base64url',
encodingVal: encodingsMap.base64url,
byteLength: (string) => base64ByteLength(string, string.length),
write: base64urlWrite,
slice: base64urlSlice,
indexOf: (buf, val, byteOffset, dir) =>
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfBuffer(buf,
fromStringFast(val, encodingOps.base64url),
byteOffset,
encodingsMap.base64url,
dir),
dir,
end),
},
hex: {
encoding: 'hex',
encodingVal: encodingsMap.hex,
byteLength: (string) => string.length >>> 1,
write: hexWrite,
slice: hexSlice,
indexOf: (buf, val, byteOffset, dir) =>
indexOf: (buf, val, byteOffset, dir, end) =>
indexOfBuffer(buf,
fromStringFast(val, encodingOps.hex),
byteOffset,
encodingsMap.hex,
dir),
dir,
end),
},
};
function getEncodingOps(encoding) {
Expand Down Expand Up @@ -1030,9 +1038,10 @@ Buffer.prototype.compare = function compare(target,
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - end - absolute exclusive end of the search range
// - encoding - an optional encoding, relevant if val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
function bidirectionalIndexOf(buffer, val, byteOffset, end, encoding, dir) {
validateBuffer(buffer);

if (typeof byteOffset === 'string') {
Expand All @@ -1052,7 +1061,7 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
dir = !!dir; // Cast to bool.

if (typeof val === 'number')
return indexOfNumber(buffer, val >>> 0, byteOffset, dir);
return indexOfNumber(buffer, val >>> 0, byteOffset, dir, end);

let ops;
if (encoding === undefined)
Expand All @@ -1063,30 +1072,48 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
if (typeof val === 'string') {
if (ops === undefined)
throw new ERR_UNKNOWN_ENCODING(encoding);
return ops.indexOf(buffer, val, byteOffset, dir);
return ops.indexOf(buffer, val, byteOffset, dir, end);
}

if (isUint8Array(val)) {
const encodingVal =
(ops === undefined ? encodingsMap.utf8 : ops.encodingVal);
return indexOfBuffer(buffer, val, byteOffset, encodingVal, dir);
return indexOfBuffer(buffer, val, byteOffset, encodingVal, dir, end);
}

throw new ERR_INVALID_ARG_TYPE(
'value', ['number', 'string', 'Buffer', 'Uint8Array'], val,
);
}

Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
Buffer.prototype.indexOf = function indexOf(val, offset, end, encoding) {
if (typeof end === 'string') {
encoding = end;
end = this.length;
} else if (end === undefined) {
end = this.length;
}
return bidirectionalIndexOf(this, val, offset, end, encoding, true);
};

Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
Buffer.prototype.lastIndexOf = function lastIndexOf(val, offset, end, encoding) {
if (typeof end === 'string') {
encoding = end;
end = this.length;
} else if (end === undefined) {
end = this.length;
}
return bidirectionalIndexOf(this, val, offset, end, encoding, false);
};

Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, true) !== -1;
Buffer.prototype.includes = function includes(val, offset, end, encoding) {
if (typeof end === 'string') {
encoding = end;
end = this.length;
} else if (end === undefined) {
end = this.length;
}
return bidirectionalIndexOf(this, val, offset, end, encoding, true) !== -1;
};

// Usage:
Expand Down
Loading
Loading