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 2fece54

Browse filesBrowse files
jasnelltargos
authored andcommitted
buffer: add Buffer.copyBytesFrom(...)
Fixes: #43862 PR-URL: #46500 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent e11f08e commit 2fece54
Copy full SHA for 2fece54

File tree

Expand file treeCollapse file tree

3 files changed

+146
-1
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+146
-1
lines changed
Open diff view settings
Collapse file

‎doc/api/buffer.md‎

Copy file name to clipboardExpand all lines: doc/api/buffer.md
+22Lines changed: 22 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,28 @@ console.log(bufA.length);
10581058
`Buffer.concat()` may also use the internal `Buffer` pool like
10591059
[`Buffer.allocUnsafe()`][] does.
10601060

1061+
### Static method: `Buffer.copyBytesFrom(view[, offset[, length]])`
1062+
1063+
<!-- YAML
1064+
added: REPLACEME
1065+
-->
1066+
1067+
* `view` {TypedArray} The {TypedArray} to copy.
1068+
* `offset` {integer} The starting offset within `view`. **Default:**: `0`.
1069+
* `length` {integer} The number of elements from `view` to copy.
1070+
**Default:** `view.length - offset`.
1071+
1072+
Copies the underlying memory of `view` into a new `Buffer`.
1073+
1074+
```js
1075+
const u16 = new Uint16Array([0, 0xffff]);
1076+
const buf = Buffer.copyBytesFrom(u16, 0, 1);
1077+
u16[1] = 0;
1078+
console.log(buf.length); // 2
1079+
console.log(buf[0]); // 255
1080+
console.log(buf[1]); // 255
1081+
```
1082+
10611083
### Static method: `Buffer.from(array)`
10621084

10631085
<!-- YAML
Collapse file

‎lib/buffer.js‎

Copy file name to clipboardExpand all lines: lib/buffer.js
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@ const {
4343
StringPrototypeTrim,
4444
SymbolSpecies,
4545
SymbolToPrimitive,
46+
TypedArrayPrototypeGetBuffer,
4647
TypedArrayPrototypeGetByteLength,
48+
TypedArrayPrototypeGetByteOffset,
4749
TypedArrayPrototypeFill,
50+
TypedArrayPrototypeGetLength,
4851
TypedArrayPrototypeSet,
52+
TypedArrayPrototypeSlice,
4953
Uint8Array,
5054
Uint8ArrayPrototype,
5155
} = primordials;
@@ -330,6 +334,48 @@ Buffer.from = function from(value, encodingOrOffset, length) {
330334
);
331335
};
332336

337+
/**
338+
* Creates the Buffer as a copy of the underlying ArrayBuffer of the view
339+
* rather than the contents of the view.
340+
* @param {TypedArray} view
341+
* @param {number} [offset]
342+
* @param {number} [length]
343+
* @returns {Buffer}
344+
*/
345+
Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
346+
if (!isTypedArray(view)) {
347+
throw new ERR_INVALID_ARG_TYPE('view', [ 'TypedArray' ], view);
348+
}
349+
350+
const viewLength = TypedArrayPrototypeGetLength(view);
351+
if (viewLength === 0) {
352+
return Buffer.alloc(0);
353+
}
354+
355+
if (offset !== undefined || length !== undefined) {
356+
if (offset !== undefined) {
357+
validateInteger(offset, 'offset', 0);
358+
if (offset >= viewLength) return Buffer.alloc(0);
359+
} else {
360+
offset = 0;
361+
}
362+
let end;
363+
if (length !== undefined) {
364+
validateInteger(length, 'length', 0);
365+
end = offset + length;
366+
} else {
367+
end = viewLength;
368+
}
369+
370+
view = TypedArrayPrototypeSlice(view, offset, end);
371+
}
372+
373+
return fromArrayLike(new Uint8Array(
374+
TypedArrayPrototypeGetBuffer(view),
375+
TypedArrayPrototypeGetByteOffset(view),
376+
TypedArrayPrototypeGetByteLength(view)));
377+
};
378+
333379
// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
334380
// Buffer() constructor. Must use arrow function syntax to avoid automatically
335381
// adding a `prototype` property and making the function a constructor.
Collapse file

‎test/parallel/test-buffer-from.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-buffer-from.js
+78-1Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const common = require('../common');
4-
const { deepStrictEqual, throws } = require('assert');
4+
const { deepStrictEqual, strictEqual, throws } = require('assert');
55
const { runInNewContext } = require('vm');
66

77
const checkString = 'test';
@@ -62,3 +62,80 @@ deepStrictEqual(
6262

6363
Buffer.allocUnsafe(10); // Should not throw.
6464
Buffer.from('deadbeaf', 'hex'); // Should not throw.
65+
66+
67+
{
68+
const u16 = new Uint16Array([0xffff]);
69+
const b16 = Buffer.copyBytesFrom(u16);
70+
u16[0] = 0;
71+
strictEqual(b16.length, 2);
72+
strictEqual(b16[0], 255);
73+
strictEqual(b16[1], 255);
74+
}
75+
76+
{
77+
const u16 = new Uint16Array([0, 0xffff]);
78+
const b16 = Buffer.copyBytesFrom(u16, 1, 5);
79+
u16[0] = 0xffff;
80+
u16[1] = 0;
81+
strictEqual(b16.length, 2);
82+
strictEqual(b16[0], 255);
83+
strictEqual(b16[1], 255);
84+
}
85+
86+
{
87+
const u32 = new Uint32Array([0xffffffff]);
88+
const b32 = Buffer.copyBytesFrom(u32);
89+
u32[0] = 0;
90+
strictEqual(b32.length, 4);
91+
strictEqual(b32[0], 255);
92+
strictEqual(b32[1], 255);
93+
strictEqual(b32[2], 255);
94+
strictEqual(b32[3], 255);
95+
}
96+
97+
throws(() => {
98+
Buffer.copyBytesFrom();
99+
}, {
100+
code: 'ERR_INVALID_ARG_TYPE',
101+
});
102+
103+
['', Symbol(), true, false, {}, [], () => {}, 1, 1n, null, undefined].forEach(
104+
(notTypedArray) => throws(() => {
105+
Buffer.copyBytesFrom('nope');
106+
}, {
107+
code: 'ERR_INVALID_ARG_TYPE',
108+
})
109+
);
110+
111+
['', Symbol(), true, false, {}, [], () => {}, 1n].forEach((notANumber) =>
112+
throws(() => {
113+
Buffer.copyBytesFrom(new Uint8Array(1), notANumber);
114+
}, {
115+
code: 'ERR_INVALID_ARG_TYPE',
116+
})
117+
);
118+
119+
[-1, NaN, 1.1, -Infinity].forEach((outOfRange) =>
120+
throws(() => {
121+
Buffer.copyBytesFrom(new Uint8Array(1), outOfRange);
122+
}, {
123+
code: 'ERR_OUT_OF_RANGE',
124+
})
125+
);
126+
127+
['', Symbol(), true, false, {}, [], () => {}, 1n].forEach((notANumber) =>
128+
throws(() => {
129+
Buffer.copyBytesFrom(new Uint8Array(1), 0, notANumber);
130+
}, {
131+
code: 'ERR_INVALID_ARG_TYPE',
132+
})
133+
);
134+
135+
[-1, NaN, 1.1, -Infinity].forEach((outOfRange) =>
136+
throws(() => {
137+
Buffer.copyBytesFrom(new Uint8Array(1), 0, outOfRange);
138+
}, {
139+
code: 'ERR_OUT_OF_RANGE',
140+
})
141+
);

0 commit comments

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