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
14 changes: 6 additions & 8 deletions lib/internal/streams/iter/consumers.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const {
TypedArrayPrototypeGetBuffer,
TypedArrayPrototypeGetByteLength,
TypedArrayPrototypeGetByteOffset,
TypedArrayPrototypeSet,
Uint8Array,
} = primordials;

const {
Expand Down Expand Up @@ -164,21 +166,17 @@ async function collectAsync(source, signal, limit) {

/**
* Convert a Uint8Array to its backing ArrayBuffer, slicing if necessary.
* Handles both ArrayBuffer and SharedArrayBuffer backing stores.
* @param {Uint8Array} data
* @returns {ArrayBuffer|SharedArrayBuffer}
* @returns {ArrayBuffer}
*/
function toArrayBuffer(data) {
const byteOffset = TypedArrayPrototypeGetByteOffset(data);
const byteLength = TypedArrayPrototypeGetByteLength(data);
const buffer = TypedArrayPrototypeGetBuffer(data);
// SharedArrayBuffer is not available in primordials, so use
// direct property access for its byteLength and slice.
if (isSharedArrayBuffer(buffer)) {
if (byteOffset === 0 && byteLength === buffer.byteLength) {
return buffer;
}
return buffer.slice(byteOffset, byteOffset + byteLength);
const copy = new Uint8Array(byteLength);
TypedArrayPrototypeSet(copy, data);
return TypedArrayPrototypeGetBuffer(copy);
}
if (byteOffset === 0 &&
byteLength === ArrayBufferPrototypeGetByteLength(buffer)) {
Expand Down
19 changes: 12 additions & 7 deletions lib/internal/streams/iter/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ function allUint8Array(chunks) {
return true;
}

function copyBytes(chunk) {
const copy = new Uint8Array(TypedArrayPrototypeGetByteLength(chunk));
TypedArrayPrototypeSet(copy, chunk);
return copy;
}

/**
* Concatenate multiple Uint8Arrays into a single Uint8Array.
* @param {Uint8Array[]} chunks
Expand All @@ -220,16 +226,15 @@ function concatBytes(chunks) {
// If non-zero offset, skip the remaining buffer checks.
if (TypedArrayPrototypeGetByteOffset(chunk) === 0) {
const buf = TypedArrayPrototypeGetBuffer(chunk);
// SharedArrayBuffer is not available in primordials, so use
// direct property access for its byteLength.
const bufByteLength = isSharedArrayBuffer(buf) ?
buf.byteLength :
ArrayBufferPrototypeGetByteLength(buf);
if (TypedArrayPrototypeGetByteLength(chunk) === bufByteLength) {
if (
!isSharedArrayBuffer(buf) &&
TypedArrayPrototypeGetByteLength(chunk) ===
ArrayBufferPrototypeGetByteLength(buf)
) {
return chunk;
}
}
return new Uint8Array(chunk);
return copyBytes(chunk);
}
// Multiple chunks: concatenate
let totalByteLength = 0;
Expand Down
6 changes: 4 additions & 2 deletions test/parallel/test-stream-iter-sharedarraybuffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ function testBytesSyncSAB() {
const sab = new SharedArrayBuffer(5);
new Uint8Array(sab).set([104, 101, 108, 108, 111]); // 'hello'
const data = bytesSync(fromSync(sab));
assert.ok(data.buffer instanceof ArrayBuffer);
assert.deepStrictEqual(data, new Uint8Array([104, 101, 108, 108, 111]));
}

async function testBytesAsyncSAB() {
const sab = new SharedArrayBuffer(5);
new Uint8Array(sab).set([104, 101, 108, 108, 111]); // 'hello'
const data = await bytes(from(sab));
assert.ok(data.buffer instanceof ArrayBuffer);
assert.deepStrictEqual(data, new Uint8Array([104, 101, 108, 108, 111]));
}

Expand All @@ -80,15 +82,15 @@ function testArrayBufferSyncSAB() {
const sab = new SharedArrayBuffer(4);
new Uint8Array(sab).set([1, 2, 3, 4]);
const result = arrayBufferSync(fromSync(sab));
assert.ok(result instanceof SharedArrayBuffer || result instanceof ArrayBuffer);
assert.ok(result instanceof ArrayBuffer);
assert.deepStrictEqual(new Uint8Array(result), new Uint8Array([1, 2, 3, 4]));
}

async function testArrayBufferAsyncSAB() {
const sab = new SharedArrayBuffer(4);
new Uint8Array(sab).set([1, 2, 3, 4]);
const result = await arrayBuffer(from(sab));
assert.ok(result instanceof SharedArrayBuffer || result instanceof ArrayBuffer);
assert.ok(result instanceof ArrayBuffer);
assert.deepStrictEqual(new Uint8Array(result), new Uint8Array([1, 2, 3, 4]));
}

Expand Down
Loading