| import {getStreamContents} from './contents.js';
|
| import {noop, throwObjectStream, getLengthProp} from './utils.js';
|
|
|
| export async function getStreamAsArrayBuffer(stream, options) {
|
| return getStreamContents(stream, arrayBufferMethods, options);
|
| }
|
|
|
| const initArrayBuffer = () => ({contents: new ArrayBuffer(0)});
|
|
|
| const useTextEncoder = chunk => textEncoder.encode(chunk);
|
| const textEncoder = new TextEncoder();
|
|
|
| const useUint8Array = chunk => new Uint8Array(chunk);
|
|
|
| const useUint8ArrayWithOffset = chunk => new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
|
| const truncateArrayBufferChunk = (convertedChunk, chunkSize) => convertedChunk.slice(0, chunkSize);
|
|
|
|
|
| const addArrayBufferChunk = (convertedChunk, {contents, length: previousLength}, length) => {
|
| const newContents = hasArrayBufferResize() ? resizeArrayBuffer(contents, length) : resizeArrayBufferSlow(contents, length);
|
| new Uint8Array(newContents).set(convertedChunk, previousLength);
|
| return newContents;
|
| };
|
|
|
|
|
|
|
|
|
| const resizeArrayBufferSlow = (contents, length) => {
|
| if (length <= contents.byteLength) {
|
| return contents;
|
| }
|
|
|
| const arrayBuffer = new ArrayBuffer(getNewContentsLength(length));
|
| new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0);
|
| return arrayBuffer;
|
| };
|
|
|
|
|
|
|
|
|
|
|
| const resizeArrayBuffer = (contents, length) => {
|
| if (length <= contents.maxByteLength) {
|
| contents.resize(length);
|
| return contents;
|
| }
|
|
|
| const arrayBuffer = new ArrayBuffer(length, {maxByteLength: getNewContentsLength(length)});
|
| new Uint8Array(arrayBuffer).set(new Uint8Array(contents), 0);
|
| return arrayBuffer;
|
| };
|
|
|
|
|
| const getNewContentsLength = length => SCALE_FACTOR ** Math.ceil(Math.log(length) / Math.log(SCALE_FACTOR));
|
|
|
| const SCALE_FACTOR = 2;
|
|
|
| const finalizeArrayBuffer = ({contents, length}) => hasArrayBufferResize() ? contents : contents.slice(0, length);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| const hasArrayBufferResize = () => 'resize' in ArrayBuffer.prototype;
|
|
|
| const arrayBufferMethods = {
|
| init: initArrayBuffer,
|
| convertChunk: {
|
| string: useTextEncoder,
|
| buffer: useUint8Array,
|
| arrayBuffer: useUint8Array,
|
| dataView: useUint8ArrayWithOffset,
|
| typedArray: useUint8ArrayWithOffset,
|
| others: throwObjectStream,
|
| },
|
| getSize: getLengthProp,
|
| truncateChunk: truncateArrayBufferChunk,
|
| addChunk: addArrayBufferChunk,
|
| getFinalChunk: noop,
|
| finalize: finalizeArrayBuffer,
|
| };
|
|
|