mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
buffer: add Buffer.copyBytesFrom(...)
Fixes: https://github.com/nodejs/node/issues/43862 PR-URL: https://github.com/nodejs/node/pull/46500 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
1 parent
3c0131a419
commit
311fb041fa
3 files changed
+146
-1
No files matched your search
@@ -1058,6 +1058,28 @@ console.log(bufA.length);
|
||||
`Buffer.concat()` may also use the internal `Buffer` pool like
|
||||
[`Buffer.allocUnsafe()`][] does.
|
||||
|
||||
### Static method: `Buffer.copyBytesFrom(view[, offset[, length]])`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* `view` {TypedArray} The {TypedArray} to copy.
|
||||
* `offset` {integer} The starting offset within `view`. **Default:**: `0`.
|
||||
* `length` {integer} The number of elements from `view` to copy.
|
||||
**Default:** `view.length - offset`.
|
||||
|
||||
Copies the underlying memory of `view` into a new `Buffer`.
|
||||
|
||||
```js
|
||||
const u16 = new Uint16Array([0, 0xffff]);
|
||||
const buf = Buffer.copyBytesFrom(u16, 0, 1);
|
||||
u16[1] = 0;
|
||||
console.log(buf.length); // 2
|
||||
console.log(buf[0]); // 255
|
||||
console.log(buf[1]); // 255
|
||||
```
|
||||
|
||||
### Static method: `Buffer.from(array)`
|
||||
|
||||
<!-- YAML
|
||||
|
||||
@@ -43,9 +43,13 @@ const {
|
||||
StringPrototypeTrim,
|
||||
SymbolSpecies,
|
||||
SymbolToPrimitive,
|
||||
TypedArrayPrototypeGetBuffer,
|
||||
TypedArrayPrototypeGetByteLength,
|
||||
TypedArrayPrototypeGetByteOffset,
|
||||
TypedArrayPrototypeFill,
|
||||
TypedArrayPrototypeGetLength,
|
||||
TypedArrayPrototypeSet,
|
||||
TypedArrayPrototypeSlice,
|
||||
Uint8Array,
|
||||
Uint8ArrayPrototype,
|
||||
} = primordials;
|
||||
@@ -330,6 +334,48 @@ Buffer.from = function from(value, encodingOrOffset, length) {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the Buffer as a copy of the underlying ArrayBuffer of the view
|
||||
* rather than the contents of the view.
|
||||
* @param {TypedArray} view
|
||||
* @param {number} [offset]
|
||||
* @param {number} [length]
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
|
||||
if (!isTypedArray(view)) {
|
||||
throw new ERR_INVALID_ARG_TYPE('view', [ 'TypedArray' ], view);
|
||||
}
|
||||
|
||||
const viewLength = TypedArrayPrototypeGetLength(view);
|
||||
if (viewLength === 0) {
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
|
||||
if (offset !== undefined || length !== undefined) {
|
||||
if (offset !== undefined) {
|
||||
validateInteger(offset, 'offset', 0);
|
||||
if (offset >= viewLength) return Buffer.alloc(0);
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
let end;
|
||||
if (length !== undefined) {
|
||||
validateInteger(length, 'length', 0);
|
||||
end = offset + length;
|
||||
} else {
|
||||
end = viewLength;
|
||||
}
|
||||
|
||||
view = TypedArrayPrototypeSlice(view, offset, end);
|
||||
}
|
||||
|
||||
return fromArrayLike(new Uint8Array(
|
||||
TypedArrayPrototypeGetBuffer(view),
|
||||
TypedArrayPrototypeGetByteOffset(view),
|
||||
TypedArrayPrototypeGetByteLength(view)));
|
||||
};
|
||||
|
||||
// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
|
||||
// Buffer() constructor. Must use arrow function syntax to avoid automatically
|
||||
// adding a `prototype` property and making the function a constructor.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const { deepStrictEqual, throws } = require('assert');
|
||||
const { deepStrictEqual, strictEqual, throws } = require('assert');
|
||||
const { runInNewContext } = require('vm');
|
||||
|
||||
const checkString = 'test';
|
||||
@@ -62,3 +62,80 @@ deepStrictEqual(
|
||||
|
||||
Buffer.allocUnsafe(10); // Should not throw.
|
||||
Buffer.from('deadbeaf', 'hex'); // Should not throw.
|
||||
|
||||
|
||||
{
|
||||
const u16 = new Uint16Array([0xffff]);
|
||||
const b16 = Buffer.copyBytesFrom(u16);
|
||||
u16[0] = 0;
|
||||
strictEqual(b16.length, 2);
|
||||
strictEqual(b16[0], 255);
|
||||
strictEqual(b16[1], 255);
|
||||
}
|
||||
|
||||
{
|
||||
const u16 = new Uint16Array([0, 0xffff]);
|
||||
const b16 = Buffer.copyBytesFrom(u16, 1, 5);
|
||||
u16[0] = 0xffff;
|
||||
u16[1] = 0;
|
||||
strictEqual(b16.length, 2);
|
||||
strictEqual(b16[0], 255);
|
||||
strictEqual(b16[1], 255);
|
||||
}
|
||||
|
||||
{
|
||||
const u32 = new Uint32Array([0xffffffff]);
|
||||
const b32 = Buffer.copyBytesFrom(u32);
|
||||
u32[0] = 0;
|
||||
strictEqual(b32.length, 4);
|
||||
strictEqual(b32[0], 255);
|
||||
strictEqual(b32[1], 255);
|
||||
strictEqual(b32[2], 255);
|
||||
strictEqual(b32[3], 255);
|
||||
}
|
||||
|
||||
throws(() => {
|
||||
Buffer.copyBytesFrom();
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
});
|
||||
|
||||
['', Symbol(), true, false, {}, [], () => {}, 1, 1n, null, undefined].forEach(
|
||||
(notTypedArray) => throws(() => {
|
||||
Buffer.copyBytesFrom('nope');
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
})
|
||||
);
|
||||
|
||||
['', Symbol(), true, false, {}, [], () => {}, 1n].forEach((notANumber) =>
|
||||
throws(() => {
|
||||
Buffer.copyBytesFrom(new Uint8Array(1), notANumber);
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
})
|
||||
);
|
||||
|
||||
[-1, NaN, 1.1, -Infinity].forEach((outOfRange) =>
|
||||
throws(() => {
|
||||
Buffer.copyBytesFrom(new Uint8Array(1), outOfRange);
|
||||
}, {
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
})
|
||||
);
|
||||
|
||||
['', Symbol(), true, false, {}, [], () => {}, 1n].forEach((notANumber) =>
|
||||
throws(() => {
|
||||
Buffer.copyBytesFrom(new Uint8Array(1), 0, notANumber);
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
})
|
||||
);
|
||||
|
||||
[-1, NaN, 1.1, -Infinity].forEach((outOfRange) =>
|
||||
throws(() => {
|
||||
Buffer.copyBytesFrom(new Uint8Array(1), 0, outOfRange);
|
||||
}, {
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
})
|
||||
);
|
||||
Reference in new issue
Block a user